Project
Roadmap
What is deferred past v0.1, and why each item was deferred.
What v0.1 ships
Section titled “What v0.1 ships”- CLI commands
init,buildandcheck. - JSON catalogs in (ICU, or i18next converted at read time); typed ESM functions out, one module per top-level key.
- Every rule in every build, with stable codes and per-rule severity.
- A per-message context record, compared by
check. - Typed lookup groups for run-time keys.
- A locale store with cookie persistence, React bindings,
AsyncLocalStoragerequest scoping for Web Fetch handlers, and a header primitive for Express and Fastify. - One example app, React on Vite: the reference implementation and the only one tested.
Deferred, and why
Section titled “Deferred, and why”Runtime format()
Section titled “Runtime format()”For content unknown at build time. It needs a runtime ICU parser, which the browser must never ship; a separate entry would keep that true for anyone not importing it. Until then, such content is not a message. Run-time keys: Dynamic keys.
--watch
Section titled “--watch”A second compiler code path, with platform-dependent recursive fs.watch and its own
severity semantics, that nothing in v0.1 needs.
The loop today is loclizr build --no-fail in predev, plus either
nodemon -w locales -x 'loclizr build --no-fail' or the small Vite plugin in the example app’s
vite.config.ts, which reruns build when a catalog changes. A 2000-key, 10-locale catalog builds
in about half a second on a laptop, so each loop is a full rebuild; a watcher would be reconsidered
only if large catalogs make that too slow.
Context record fields
Section titled “Context record fields”The record says where a string is used, never what it is.
| Field | Why not yet |
|---|---|
| Glossary hits | Cheap, deterministic, first in line. Its motivating number (terminology retrieval gains in machine translation) is single-vendor and unreproduced, so it does not gate a first release. |
| Surrounding copy | The record has each usage’s file and enclosing scope. Nearby text means reading the component, and the scan is a tokenizer, not a parser. |
| Element role | Button, heading or tooltip is a JSX tree question the scan cannot answer. |
Extraction and instrumentation
Section titled “Extraction and instrumentation”v0.1 never finds string literals in components or rewrites them into message calls: that needs a bundler AST pass, the tax this project avoids. A retrofit would be a separate opt-in command, run once, outside the build.
Next.js App Router server rendering
Section titled “Next.js App Router server rendering”Middleware runs in another runtime and cannot wrap a render; the root layout entry point is open.
No test, no example, no claim. The message layer runs anywhere; the Pages Router reaches
runWithLocale through localeFromHeaders.
URL-prefix locale routing
Section titled “URL-prefix locale routing”Hydration agrees because the locale comes from a cookie or Accept-Language, never the path.
A /de/cart prefix is a second channel to keep in agreement: the router’s job.
Per-locale delivery
Section titled “Per-locale delivery”Every locale is inlined into each message function, so bundle size grows with locale count. One locale per request needs the metaframework’s build, which this compiler stays out of. Sizes are on Limits.
What would change the order
Section titled “What would change the order”Bug reports against the example app, and catalogs large enough to make build slow. Continuity
covers how the project is run.