Email Validation in JavaScript: How It Works Under the Hood (Code Analysis)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Validate Email in JavaScript: From Simple Regex to Full Under-the-Hood Analysis

\n\n

Every developer has encountered the question at least once: «How can I validate an email address in JavaScript?». This question on Stack Overflow has gathered thousands of views and hundreds of answers because the topic is a real tangle of nuances. Today we won't just provide ready-made code, but will look under the hood: we'll analyze why a simple check might allow a@b or block "test@[IPv6:2001:db8::1]". Let's go!

\n\n

Why is «just regex» a bad idea?

\n\n

The most popular solution on the internet is to copy a regular expression. But let's be honest: email addresses are chaos. The RFC 5321 and RFC 5322 specifications allow the use of characters like +, -, ., %, and even comments in parentheses. There are also domains like museum or @[192.168.1.1]. Try to fit all of this into a single regex line — and you will either allow an invalid address or block a real user.

\n\n

Here's an example often found on Stack Overflow:

\n\n
const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
\n\n

This code works for 90% of cases, but:

\n
    \n
  • Allows test@localhost (valid for a local network)
  • \n
  • Blocks "test@[192.168.1.1]" (valid per RFC)
  • \n
  • Does not check domain length or the presence of dots
  • \n
\n\n

The moral: don't try to write a perfect regex. It's better to use a combination of a simple check + server-side validation.

\n\n

Anatomy of an Email Address: What You Need to Know Before Writing Code

\n\n

Before writing a validator, let's break down the email structure according to the specification:

\n\n
    \n
  • Local part (before @): can contain letters, numbers, dots, plus signs, hyphens, but cannot start or end with a dot. Quoted strings are allowed for special characters.
  • \n
  • Domain (after @): consists of labels separated by dots. Each label is from 1 to 63 characters. The domain can be an IP address in square brackets.
  • \n
  • Total length: no more than 254 characters.
  • \n
\n\n

Knowing this, we can write a more meaningful check.

\n\n

Step 1: Simple but Functional Validation (for 99% of cases)

\n\n

Let's start with code used in production projects (e.g., in Angular or React). It's not perfect, but sufficient for most forms:

\n\n
function isEmailSimple(email) {\n    // Remove whitespace\n    const trimmed = email.trim();\n    \n    // Check for empty string\n    if (!trimmed) return false;\n    \n    // Basic structure: something @ something . something\n    const atIndex = trimmed.lastIndexOf('@');\n    if (atIndex < 1 || atIndex === trimmed.length - 1) return false;\n    \n    const localPart = trimmed.slice(0, atIndex);\n    const domain = trimmed.slice(atIndex + 1);\n    \n    // Domain must contain at least one dot\n    const dotIndex = domain.lastIndexOf('.');\n    if (dotIndex < 1 || dotIndex === domain.length - 1) return false;\n    \n    // Length check\n    if (trimmed.length > 254) return false;\n    if (localPart.length > 64) return false;\n    \n    return true;\n}\n\n// Examples:\nconsole.log(isEmailSimple('user@example.com')); // true\nconsole.log(isEmailSimple('a@b.c')); // true (formally valid)\nconsole.log(isEmailSimple('user@localhost')); // false (no dot)\nconsole.log(isEmailSimple('@example.com')); // false\n
\n\n

This code is already better than a blind regex. It checks the structure, length, and the presence of @ with a dot. But it allows user@[192.168.1.1] — for most web forms, this is not critical.

\n\n

Step 2: Advanced Validation Considering RFC (almost like in the browser)

\n\n

Modern browsers use built-in validation via the type="e

Blogs

Book Recommendations