“Email validation in JavaScript” is searched about 600 times a month in India, and “email regex” roughly 700 times. Most searchers are developers building a signup form, a lead capture page,e or a KYC onboarding flow, and they want a pattern that works.
This guide provides practical patterns, explains the trade-offs behind them, and draws a clear line most tutorials skip: regex validates format, not existence. For any product where a wrong email costs money, format validation is the first check, not the only one.
What Email Validation Actually Means
Email checks happen at three distinct levels:
| Level | Question | Method |
|---|---|---|
| Syntax | Is it formatted like an email? | Regex, HTML5 input type |
| Domain | Can this domain receive mail? | DNS and MX record lookup |
| Mailbox | Does this specific inbox exist and accept mail? | SMTP verification, risk scoring |
Regex belongs only to the first level. Our overview of email validation methods and email validation vs email verification covers the distinction in depth.
The HTML5 Baseline
Before writing any regex, use the platform:
<input type=”email” name=”email” required autocomplete=”email”>
Browsers apply a well-defined pattern from the HTML specification, show native error messages (“Please enter a valid email address”), and present the right mobile keyboard. You can read the same check in JavaScript:
const input = document.querySelector(‘input[type=”email”]’);
if (!input.checkValidity()) {
console.log(input.validationMessage);
}
This is sufficient for many forms and consistent with user expectations.
Practical Email Regex Patterns for JavaScript
Pattern 1: Pragmatic default
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
function isValidEmailFormat(email) {
return EMAIL_RE.test(email.trim());
}
It requires exactly one @, no whitespace, a dot in the domain, and a TLD of at least two characters. It rejects obvious errors without rejecting legitimate addresses. For most products, this is the right choice.
Pattern 2: Stricter, aligned with HTML5
const EMAIL_STRICT_RE =
/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
This is based on the browser’s own rule, with valid characters in the local part and properly formed domain labels. One deliberate difference: the HTML specification allows a domain
with no dot (such as user@localhost), while this version uses + instead of * on the final group to require at least one dot. Use it when you want server-side behaviour to closely match client-side behaviour for public-facing forms.
Normalise before you test
function normaliseEmail(raw) {
return raw.trim().toLowerCase();
}
Trim spaces pasted from WhatsApp or spreadsheets, and lowercase the domain. Be cautious about altering the local part beyond lowercasing; some providers treat dots and plus-tags differently.
Why the “Perfect” Email Regex Is a Trap
The email address standard (RFC 5322) permits quoted local parts, comments, and unusual characters. A regex implementing the full specification runs to thousands of characters, is nearly impossible to maintain, and still cannot tell you whether the address works.
Worse, strict patterns reject real users. Addresses with plus-tags (name+orders@gmail.com), apostrophes (o’brien@company.com), long TLDs (.technology), and subdomains (user@mail.company.co.in) are legitimate and frequently rejected by over-engineered patterns.
The goal of syntax validation is to catch typos, not to police edge cases.
Common Validation Mistakes
- Limiting TLDs to 2–4 characters. Hundreds of longer TLDs exist.
- Rejecting plus signs. Common among Gmail users filtering their inbox.
- Blocking .co.in or multi-level domains. A frequent error on Indian sites.
- Validating only on the client. Anyone can bypass browser checks; validate again on the server.
- Blocking paste into email fields. It frustrates users and increases typos.
- Silent failure. Always tell users what is wrong in plain language.
What Regex Cannot Catch
Every one of these passes a correct regex:
- rahul@gmial.com: a typo of a real provider; the domain may not exist.
- test@company-that-shut-down.in: valid format, no mail server.
- priya@company.com: domain is real, mailbox deleted when she left.
- abc123@tempmail-provider.com: disposable address that expires in minutes. See disposable email addresses.
- info@company.com: role address, deliverable but low-quality for many use cases.
For an Indian fintech onboarding customers, an edtech capturing leads, or a SaaS running free trials, these addresses cause failed OTPs, bounced statements, trial abuse, and polluted CRM data.
A Layered Validation Architecture
Layer 1: Client-side format check
HTML5 input plus a pragmatic regex for instant feedback.
Layer 2: Typo suggestion
Compare the domain against common providers (gmail.com, yahoo.co.in, outlook.com, rediffmail.com) and prompt: “Did you mean gmail.com?”
Layer 3: Server-side format check
Repeat the regex server-side. Never trust the client.
Layer 4: Domain check
Confirm the domain has MX records. Our MX record lookup guide explains this step.
Layer 5: Real-time verification API
Call a verification API on submit to confirm the mailbox and flag disposable, role-based,d and catch-all addresses. Our email verification API best practices cover timeouts, caching, and fallbacks.
Layer 6: Ownership confirmation
For accounts, send an OTP or confirmation link. See email OTP verification vs address verification.
async function validateEmail(email) {
const e = normaliseEmail(email);
if (!EMAIL_RE.test(e)) return { ok: false, reason: ‘format’ };
// Server-side call to your backend, which calls the verification API
const res = await fetch(‘/api/verify-email’, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({ email: e })
});
const { status } = await res.json(); // e.g. valid | invalid | risky | disposable
if (status === ‘invalid’ || status === ‘disposable’) {
return { ok: false, reason: status };
}
return { ok: true, status };
}
Keep the API key on the server, and fail open with a soft warning if the verification call times out, so a genuine user is never blocked by a network issue.
Key Takeaways
- Regex validates format only, never existence or deliverability.
- Start with HTML5 type=”email” and a pragmatic regex.
- Avoid over-strict patterns that reject plus-tags, long TLDs, or .co.in domains.
- Always validate on the server as well as the client.
- Add MX checks, real-time verification, and OTP confirmation for high-value flows.
Frequently Asked Questions
A pragmatic pattern such as /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/ suits most forms. Use the HTML5-aligned pattern if you need identical client and server behaviour.
No. Regex only checks format. Existence requires domain and mailbox verification.
Both. Client-side checks improve user experience; server-side checks protect your data because client code can be bypassed.
Use a verification API that identifies disposable providers in real time. Static blocklists go out of date quickly. See stopping fake SaaS signups.
The browser’s built-in validation found a format problem, such as a missing @, spaces, or an incomplete domain.
Conclusion
Regex is a useful, cheap first filter, and a pragmatic pattern will serve most Indian products well. The mistake is expecting it to do more. A perfectly formatted address can still bounce, expire, or belong to someone who never intended to be your customer.
Treat validation as layers. Catch typos in the browser, confirm the domain on the server, verify the mailbox in real time, and confirm ownership with an OTP where it matters. Each layer is simple on its own; together they keep your database accurate from the first form submission.
