`@palamedes/core`
Palamedes v2 executes compiled catalogs through one parser-free runtime on server and client. ICU is an authoring, translation, validation and compilation format. Framework adapters own ordinary catalog delivery; explicit catalog loading remains available for standalone/custom integrations.
@palamedes/core
Exports
The package root and @palamedes/core/compiled share the same implementation.
Their complete generated inventories follow. CompiledPalamedesI18n is a type
alias for PalamedesI18n. Build packages and run pnpm check:core-api-reference
to verify source, declarations, ESM and CJS exports.
| Export | Kind |
|---|---|
CatalogMessage | Type-only |
CatalogMessages | Type-only |
CompiledCatalogMessages | Type-only |
CompiledMessage | Type-only |
CompiledMessageBranch | Type-only |
CompiledMessageBranches | Type-only |
CompiledMessageRuntime | Type-only |
CompiledPalamedesI18n | Type-only |
createCompiledMessageRuntime | Runtime |
createI18n | Runtime |
CreateI18nOptions | Type-only |
DEFAULT_LOCALE | Runtime |
defineCompiledCatalog | Runtime |
ExecutableMessageRenderer | Type-only |
formatMessageArgument | Runtime |
isCompiledCatalog | Runtime |
MessageFormat | Type-only |
MessageFormatErrorInfo | Type-only |
MessageMetadata | Type-only |
MessageValues | Type-only |
MissingCompiledMessageError | Runtime |
MissingMessageInfo | Type-only |
PalamedesI18n | Type-only |
PluralProps | Type-only |
replacePoundPlaceholders | Runtime |
SelectOrdinalProps | Type-only |
SelectProps | Type-only |
stringifyValue | Runtime |
| Export | Kind |
|---|---|
CatalogMessage | Type-only |
CatalogMessages | Type-only |
CompiledCatalogMessages | Type-only |
CompiledMessage | Type-only |
CompiledMessageBranch | Type-only |
CompiledMessageBranches | Type-only |
CompiledMessageRuntime | Type-only |
CompiledPalamedesI18n | Type-only |
createCompiledMessageRuntime | Runtime |
createI18n | Runtime |
CreateI18nOptions | Type-only |
DEFAULT_LOCALE | Runtime |
defineCompiledCatalog | Runtime |
ExecutableMessageRenderer | Type-only |
formatMessageArgument | Runtime |
isCompiledCatalog | Runtime |
MessageFormat | Type-only |
MessageFormatErrorInfo | Type-only |
MessageMetadata | Type-only |
MessageValues | Type-only |
MissingCompiledMessageError | Runtime |
MissingMessageInfo | Type-only |
PalamedesI18n | Type-only |
PluralProps | Type-only |
replacePoundPlaceholders | Runtime |
SelectOrdinalProps | Type-only |
SelectProps | Type-only |
stringifyValue | Runtime |
createI18n(options?)
Creates an isolated instance with initial locale (default "en"), optional
IANA timeZone, and optional onMissing/onError observers. Use identical time
zones during server rendering and hydration. Invalid or empty zones throw
RangeError at construction. Dates/timestamps represent instants; date-only ISO
strings such as "2026-06-12" retain their civil calendar date in every zone.
A standalone integration can load generated modules explicitly:
import { createI18n } from "@palamedes/core";
import { messages } from "./generated/de.js";
const i18n = createI18n({ locale: "de", timeZone: "Europe/Berlin" });
i18n.load("de", messages);load() accepts only branded CompiledCatalogMessages: constants are already
compiled literal strings; dynamic messages are executable functions. An
unbranded ICU string map is rejected. CatalogMessages remains a type for
build-time string data; it is not a runtime loading input. Do not mark ICU
patterns with defineCompiledCatalog() to bypass compilation: that function
brands constants, it does not compile ICU.
PalamedesI18n
interface PalamedesI18n {
readonly locale: string;
readonly timeZone?: string;
_(id: string, values?, metadata?): string;
load(locale: string, messages: CompiledCatalogMessages): void;
activate(locale: string): void;
renderMessage<TResult>(id, values, runtime, metadata?): TResult;
}_() executes a compiled message as text. renderMessage() executes the same
message with a host renderer created by createCompiledMessageRuntime(), which
supplies shared select/plural behavior. React, Solid and Remix provide their
own rich renderers. Later catalog loads add or override entries for that locale.
Invalid entry types are rejected before the existing catalog is modified.
A missing compiled entry throws MissingCompiledMessageError. Its id,
locale and optional metadata identify the failure for developer diagnostics;
the error message itself does not expose the internal ID. Use ordinary host
error handling with an independently usable error view. Delivery failure is
not translation fallback: missing translations are resolved and compiled at
build time, following configured fallback locales and then the source message.
onMissing observes misses, and onError receives { id, locale, error, metadata } for execution failures. Neither a hook return value nor a thrown
observer error can turn failure into successful message output. Formatter
errors and missing required values propagate rather than rendering source
patterns or IDs.
MessageMetadata
The optional { message, context, comment } record preserves authored identity
for diagnostics only. No field supplies replacement runtime output. The old
reportMissing and renderUncompiledPattern controls are removed.
Locale Controls
@palamedes/core/locale exposes headless locale helpers used by the example
matrix and reusable in apps:
| Export | Kind |
|---|---|
buildLocaleSwitchItems | Runtime |
BuildLocaleSwitchItemsOptions | Type-only |
defineLocaleControls | Runtime |
HostLocaleConfig | Type-only |
LocaleControls | Type-only |
LocaleControlsConfig | Type-only |
LocaleSource | Type-only |
LocaleSuggestion | Type-only |
LocaleSwitchItem | Type-only |
parseAcceptLanguage | Runtime |
parseAcceptLanguage(header): parses and quality-sortsAccept-Languagetags, including base-language fallbacks.buildLocaleSwitchItems(options): builds UI-agnostic switch items with labels, active state, locale, and test ids.defineLocaleControls(config): binds locale resolution, deliberate-choice cookies, canonical URLs, and suggestion decisions for cookie, route, subdomain, and tld strategies. Host-carrying URLs fromcanonicalUrlandsuggestare protocol-relative (//host/path) unless the config setsprotocol(e.g."https"), so HTTPS pages never link users tohttp://. Invalid configuration is rejected at construction time with field-specific errors. Cookie names, protocols, configured hosts, and TLD labels are validated; locale identifiers must be DNS-safe only for the host-basedsubdomainandtldstrategies.
Macro Entry Point
Macros are imported from @palamedes/core/macro and must be compiled by a
Palamedes plugin before runtime.
| Export | Kind |
|---|---|
ChoiceMacroMetadata | Type-only |
plural | Runtime |
PluralMacroProps | Type-only |
select | Runtime |
SelectMacroProps | Type-only |
selectOrdinal | Runtime |
SelectOrdinalMacroProps | Type-only |
t | Runtime |
Supported macro names:
tpluralselectselectOrdinal
All four macros resolve translations eagerly. They must therefore be used inside a function, method, or callback, after the application has activated the relevant i18n scope. Palamedes rejects these macros at module scope during transformation and extraction. Class field initializers, including instance fields, do not satisfy this syntactic rule; use a method or getter instead.
Runtime Formatting
Compiled messages support values, rich-text tags, select, plural and
selectordinal, ICU apostrophe quoting, plural offsets, and the supported Intl
formatter subset. Number styles are omitted/default, percent, integer,
::percent, ::integer, and ::currency/ISO; date/time styles are omitted,
short, medium, long, or full. Invalid or unsupported ICU fails
compilation. Invalid formatter values throw during execution.
formatMessageArgument() exposes the same cached Intl formatting for custom
compiled renderers. replacePoundPlaceholders() formats plural pound values,
and stringifyValue() renders scalar values. These helpers do not parse ICU.
parseMessagePattern(), formatMessagePattern(), getMessage(),
getMessageNodes(), parsePattern(), parsed-node types, resolveChoice(),
buildChoiceMessage() and reportError() are removed from application runtime
exports. Compile authoring catalogs with the existing compiler/tooling APIs;
custom renderers should implement the compiled ABI. See the
v2 runtime migration guide for concrete replacements.