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 11 apps in this directory
DenchClaw
CRM · AI Agents
An AI-native CRM you self-host on your own machine, built on the OpenClaw agent framework, with a DuckDB backend and pre-built agent skills for managing contacts, deals, reports, and 500+ outreach integrations from natural-language chat.
Firecrawl
AI Development · Developer Tools
Turn any website into clean, LLM-ready data with a single API call — no proxy headaches, no scraping complexity.
Logto
Authentication
Open-source auth infrastructure for SaaS and AI apps with OIDC, SAML, and RBAC
n8n
Automation · No Code Platforms
Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.
Pake
Developer Tools
Turn any webpage into a lightweight native desktop app with one command — built on Rust/Tauri instead of Electron, producing installers nearly 20x smaller (typically under 10MB) for macOS, Windows, and Linux.
Rocket.Chat
Team Chat
The secure, self-hosted team communications platform for organizations that cannot compromise on data sovereignty.
Sourcebot
Search · Developer Tools · AI Code Assistants
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.
ToolJet
Low Code Platforms · No Code Platforms · AI Agents
Open-source AI-native platform to build and deploy internal tools, workflows, and AI agents with a visual drag-and-drop builder and 80+ data source integrations.
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.