How pslr compares to other PSL libraries

The Public Suffix List website catalogs implementations in C, C#, C++, Go, Haskell, Java, JavaScript, Perl, PHP, Python, Ruby, Rust, Swift, and more — but no R. pslr fills that gap, and it is built to be a reproducibility- and correctness-first engine rather than a quick suffix splitter.

The table compares pslr with a representative set of the most established libraries from that catalog, across the dimensions that matter for correct, auditable suffix handling. ✅ first-class · ◐ partial/limited · ⚠ with a caveat · ❌ absent.

Library (language) Full algorithm (*/!) ICANN / PRIVATE / both IDN + Punycode Offline default + explicit refresh Queryable provenance Compiled core Strict input validation Unlisted-TLD policy configurable
pslr (R) ✅ ✅ 3-way ✅ in & out ✅ bundled; validated HTTPS-only psl_refresh() ✅ list and normalization identity ✅ cpp11 ✅ rejects URLs, IPv4, IPv6 ✅ unknown=
libpsl (C) ✅ ✅ 3-way ✅ ✅ bundled; OS-package update ◐ sha1 + mtime ✅ ◐ ✅
x/net/publicsuffix (Go) ✅ ◐ icann flag ❌ ASCII only ✅ embedded; bump module ◐ date constant ✅ ◐ ❌
publicsuffix-go (Go) ✅ ◐ toggle private ✅ ✅ embedded ❌ ❌ ◐ ✅
psl crate (Rust) ✅ ◐ per-suffix type ✅ ✅ compiled-in ◐ dated releases ✅ ❌ ◐
tldextract (Python) ✅ ◐ private on/off ✅ ⚠ network-first; offline opt-in ❌ ❌ ◐ ❌
publicsuffixlist (Python) ✅ ◐ exclude private ✅ ✅ bundled + updater ◐ date in version ❌ ❌ ❌
public_suffix (Ruby) ✅ ◐ ignore_private ❌ caller pre-encodes ✅ bundled ❌ ❌ ◐ ✅
php-domain-parser (PHP) ✅ ✅ 3-way ✅ ⚠ not bundled; PSR-16 cache ◐ isKnown flags ❌ ◐ ◐
tldts (JS/TS) ✅ ◐ allowPrivateDomains ✅ ✅ embedded; npm bump ◐ submodule pin ◐ optional WASM ✅ ◐
Guava InternetDomainName (Java) ◐ ✅ registry vs public ✅ ◐ in-jar; bump Guava ❌ ❌ ◐ ❌

What pslr does differently

Trade-offs