psl
A lightweight JavaScript domain parser that resolves any hostname against the Public Suffix List.
Repository Health
Technical Analysis
psl is a JavaScript implementation of Mozilla’s Public Suffix List, letting you split any hostname into its top-level domain, registrable domain, and subdomain parts. Rather than relying on naive heuristics like counting dots, it looks up each label against the community-maintained suffix rules, correctly handling multi-part suffixes like co.uk, wildcard rules like *.kobe.jp, and exceptions, plus punycode-encoded internationalized domain names.
Published as psl on npm with tens of millions of weekly downloads, it ships as ESM, CommonJS, and a UMD bundle for direct browser use via CDN, and is a foundational dependency inside tools like tough-cookie/request for correct cookie-domain scoping.
What You Get
- psl.parse(domain) returns the full breakdown into tld/sld/domain/subdomain, plus a typed error object for malformed input instead of throwing
- psl.get(domain) is a quick-lookup helper that returns just the registrable domain, or null if the input isn’t valid
- psl.isValid(domain) returns a boolean for whether a domain has a recognized public suffix
- Prebuilt ESM, CJS, and UMD bundles plus bundled TypeScript type definitions, so it drops into Node, a bundler, or a plain
<script>tag from a CDN
Common Use Cases
- Scoping cookies to the correct registrable domain instead of an entire public suffix, preventing cross-site cookie leakage
- Splitting a multi-tenant SaaS hostname into its subdomain and base domain for tenant routing
- Normalizing domains (e.g. www.acme.com and acme.com) to the same registrable domain for analytics or deduplication
- Validating user-submitted domain fields before storing or looking them up
Under The Hood
Architecture
The entire library is effectively one data structure plus three pure functions built on top of it: data/rules.js (regenerated from publicsuffix.org via scripts/update-rules.js) is folded at load time in index.js into a Map keyed by punycode-encoded suffix, so findRule() can resolve a domain’s matching rule by walking candidate suffixes from most-specific to least. parse(), get(), and isValid() are thin layers on top of that single lookup — there’s no class hierarchy, dependency injection, or I/O beyond the bundled rules data. Because parse, findRule, and validate all share the same rule-object shape (wildcard/exception/punySuffix), changing that representation would require touching all three together.
Tech Stack
Plain JavaScript authored as an ES module, with a single runtime dependency (punycode v2) for IDN handling. Vite builds the ESM/CJS/UMD bundles, and TypeScript (via typescript-eslint) is used only to author and check the bundled .d.ts definitions, not to compile the runtime code. Tests run on Mocha with Node’s built-in assert, alongside a separate BrowserStack/Playwright suite for real-browser coverage. There is no framework, ORM, or database — this is a pure parsing utility.
Code Quality
Test coverage is thorough for a library this size: dedicated spec files for parse, get, and isValid run against Mozilla’s own canonical PSL test fixtures as well as hand-written cases for wildcards, exceptions, and punycode-encoded IDNs. Invalid input is modeled as typed, explicit error codes rather than swallowed or thrown for expected cases, while true programmer errors (a non-string input) raise a TypeError. ESLint’s flat config with typescript-eslint recommended rules, plus a GitHub Actions matrix spanning legacy and current Node versions and browsers, run on every push.
What Makes It Unique
psl doesn’t invent a new algorithm — domain-suffix matching against the canonical Public Suffix List is a well-understood problem — but it’s one of the most widely adopted JavaScript implementations of it, embedded inside libraries like tough-cookie/request for correct cookie scoping, and its compact rules-array-plus-Map lookup is a pragmatic, extensively tested reference implementation rather than a novel technique.
Used by 12 apps in this directory
twenty
CRM
The open-source CRM you build, ship, and version like the rest of your stack — with customizable objects, AI agents, and a TypeScript SDK.
VoidAuth
Authentication · Security
Self-hosted SSO with OIDC, LDAP, passkeys, and proxy auth for your entire self-hosted stack
web-check
Developer Tools · Security
All-in-one OSINT dashboard that dissects any website's IP, SSL, DNS, headers, cookies, ports, trackers, and more in a single scan.