email-addresses
A dependency-free RFC 5322 email address parser for JavaScript and Node.js.
Repository Health
Technical Analysis
email-addresses is a JavaScript library that parses email addresses and address lists against the full grammar defined in RFC 5322, rather than relying on a regular expression approximation. It exposes helper functions for the common header shapes found in real email traffic — a single address, a comma-separated address list, and the From, Sender, and Reply-To headers — returning structured results with the display name, address, local part, and domain already extracted.
Because the parser is a literal recursive-descent implementation of the RFC 5322 grammar (with optional RFC 6532 Unicode support), it correctly accepts constructs that regex-based validators typically get wrong, such as quoted display names, comments, and address groups, while still returning null for genuinely malformed input. It ships as a single dependency-free file that works in both Node.js and the browser.
What You Get
- A recursive-descent parser that mirrors the RFC 5322 grammar productions one-to-one, so behavior can be verified directly against the spec
- Purpose-built entry points for the header shapes email systems actually see: parseOneAddress, parseAddressList, parseFrom, parseSender, and parseReplyTo
- Structured results with name, address, local, and domain already pulled out, plus the full AST for callers that need raw tokens or semantic values
- Support for RFC 6532 (Unicode/internationalized addresses), RFC 5322 ‘obsolete’ syntax toggling via a strict option, and address groups (e.g. ‘Team: a@x.com, b@x.com;’)
- Zero runtime dependencies and bundled TypeScript typings, usable directly in Node.js or in the browser
Common Use Cases
- Validating that a signup or contact form field looks like a well-formed email address before accepting it
- Parsing ‘From’, ‘Sender’, and ‘Reply-To’ headers when processing inbound email in a mail-handling service
- Splitting a comma-separated recipient field into individual addresses with display names for a mail client or CRM
- Extracting the domain portion of an address for allow-list/deny-list or deliverability checks
Under The Hood
Architecture — The entire parser lives in a single ~1,100-line file (lib/email-addresses.js) built as a hand-written recursive-descent parser using small combinator helpers — and(), or(), opt(), star(), and literal() — that compose into functions named directly after RFC 5322 grammar productions (e.g. addrSpec, angleAddr, mailboxList). Each production function is preceded by a comment quoting the exact RFC ABNF rule it implements, which keeps the code auditable against the spec rather than against test cases alone. Parsing produces an AST of {name, tokens, semantic, children} nodes; a post-parse walk over specific parts (name/address/local/domain) builds the convenience fields returned by parseOneAddress and friends. The five public entry points are thin wrappers around a shared parse5322(opts) core that differ only in default options and startAt grammar production.
Tech Stack — Plain ES5 JavaScript (var-based, no build step, no transpilation) wrapped in a UMD-style IIFE that assigns module.exports under Node/CommonJS and falls back to a global.emailAddresses global in the browser. There are no runtime dependencies at all — package.json lists an empty devDependencies object, and tests run via Node’s built-in node --test runner rather than an external framework. Hand-written TypeScript declarations (lib/email-addresses.d.ts) are shipped alongside the JS for typed consumers.
Code Quality — test/email-addresses.js (369 lines) covers the public API surface — options handling, groups, RFC 6532, strict mode — and test/is_email.js (56 lines) replays the extensive third-party test corpus from the is_email project referenced in the README, giving the parser broad coverage against known edge cases in the wild. There is no TypeScript source or JSDoc-level type checking on the implementation itself (only hand-maintained .d.ts typings), and the code predates modern JS conventions (no const/let, no arrow functions), but naming is consistent and the grammar-production mapping doubles as inline documentation.
API Design — The public surface is deliberately small: one low-level entry point (parse5322) plus five task-specific wrappers, all sharing the same options object shape. Sensible defaults mean the common case (parseOneAddress('a@b.com')) requires no configuration, while options like strict, rejectTLD, and atInDisplayName are available for callers with stricter validation needs. The README documents every option and return field with worked examples, and returning null on failed parses (rather than throwing) keeps validation call sites simple.
Used by 7 apps in this directory
Authgear
Authentication
Open-source, self-hostable authentication platform with passkeys, biometric login, SSO, MFA, and GraphQL admin API — a full Auth0/Clerk/Firebase alternative for SaaS and mobile apps.
Huly Platform
Project Management · Team Chat · Collaboration
Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.
Kibana
Analytics · Monitoring
Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.
Openship
Devops · Hosting Control Panel
Openship is an open-source, self-hostable deployment platform that points at a repo and builds, ships, routes, and TLS-terminates the app — driven from a desktop app, web dashboard, or CLI.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
Webiny JS
Ecommerce · Blogging · CMS
Open-source, self-hosted CMS on AWS serverless — a TypeScript framework you extend with code, not a product you configure through a UI.
Zulip
Team Chat
Topic-based team chat that brings the structure of email threads to real-time messaging, so distributed teams never lose context across hundreds of concurrent conversations.