npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vouchington/localization-compiler

v0.2.2

Published

Node compiler for localization JSON catalogs, immutable SQLite artifacts, and CLI resolution.

Readme

@vouchington/localization-compiler

Node-only compiler for @vouchington/localization. It validates row-based JSON catalogs, requires complete en-US with sparse partial locales, emits an immutable read-only SQLite artifact, and exposes the same consumer/locale/selector resolver used by application CLIs.

Catalog source has three canonical tables: copies.json ({ id, descriptor }), aliases.json ({ consumer, alias, copyId }), and translations/<locale>.json ({ id, value }). A generated routes.json accepts legacy { consumer, selectorId, alias } rows while generated source moves to { consumer, pattern, alias? } rows. A presence-only pattern row records a known empty route; the compiler derives stable per-selector IDs from its sorted aliases, expands alias membership, and persists the complete exact-selector registry. An unknown exact selector therefore produces an empty v1 message batch, while a known empty selector can still resolve requested chrome. Full plural and select-plural translation values remain values in the locale table.

vouchington-localization upsert --file localization/catalog/copies.json --row '{"id":"copy.ok","descriptor":null}'
vouchington-localization upsert --file localization/catalog/aliases.json --row '{"consumer":"web","alias":"web.common.ok","copyId":"copy.ok"}'
vouchington-localization upsert --file localization/catalog/translations/en-US.json --row '{"id":"copy.ok","value":"OK"}'
vouchington-localization remove --file localization/catalog/aliases.json --id web.common.ok --consumer web
vouchington-localization format --source localization/catalog
vouchington-localization format --check --source localization/catalog

remove throws the exported CatalogRowNotFoundError (a TypeError with code: 'ERR_CATALOG_ROW_NOT_FOUND', id, and consumer) when no row matches. Callers that want idempotent removes should catch it by class or code, never by message text.

format --check reads the same managed catalog tables as format, validates the complete catalog, and exits nonzero when a table needs canonicalization or violates catalog semantics. It never writes source files, so use it in CI; use format to rewrite rows. tags.json remains outside formatter ownership.

Git merge is 3-way by message id, then by field (configure once per clone). Adding es on one branch and fr on the other auto-merges when both sides keep a compile-valid shape. An empty %O (add/add of a new shard) is treated as []. Both sides changing the same locale, descriptor, or deleting vs editing the same id is a conflict.

localization/catalog/*.json merge=vouchington-localization text eol=lf
localization/catalog/tags.json merge=text
[merge "vouchington-localization"]
  name = Merge localization catalog shards by message id and locale
  driver = vouchington-localization git-merge %O %A %B --path %P

On conflict the driver retains every automatically merged row plus conflict markers for only the conflicting rows, then exits non-zero. Resolve each row without editing JSON directly:

vouchington-localization conflict-resolve --file localization/catalog/copies.json --id copy.save --take ours
vouchington-localization conflict-resolve --file localization/catalog/aliases.json --id web.nav.save --consumer web --take theirs
vouchington-localization conflict-resolve --file localization/catalog/routes.json --id web.nav.save --consumer web --selector-id web.route.home --take ours

The command leaves any other row conflicts in place. After the final resolution it writes a canonical table, ready to stage. A conflicted table must not be compiled.

CSV import/export is interchange only: never source of truth and never compiled directly to SQLite. It covers only the three authoring tables (copies, aliases, translations); generated route membership/selectors and editorial tags are excluded, so regenerate them from routes.json and tags.json instead of round-tripping them through CSV. Native resource helpers emit strings, RESX, and typed key/descriptor files from the same resolved catalog without product path assumptions.