@palamedes/transform
v1.25.0
Published
Native macro transformer for Palamedes macros without Babel
Maintainers
Readme
@palamedes/transform
Low-level macro transformation powered by Palamedes' native core.
This package turns supported message macro imports into runtime calls without requiring Babel. It is the building block behind the framework adapters and the right entry point when you want to embed Palamedes in your own bundler, compiler, or tooling flow.
Palamedes stays source-string-first at the public model level. The transform may emit a compact internal lookup key, but that key is a runtime artifact, not a user-facing message ID.
When To Use This Package
Use @palamedes/transform when you are:
- building a custom integration outside the official plugins
- experimenting with your own compile pipeline
- working on Palamedes internals
If you are integrating Palamedes into an app, start with @palamedes/vite-plugin or @palamedes/next-plugin instead.
Installation
pnpm add @palamedes/core
pnpm add -D @palamedes/transformGenerated catalog modules import defineCompiledCatalog() from
@palamedes/core/compiled, so @palamedes/core must be a direct runtime
dependency when using the catalog-loader helpers.
Minimal Example
import { transformPalamedesMacros } from "@palamedes/transform";
const result = transformPalamedesMacros(
'import { t } from "@palamedes/core/macro"; function message(name) { return t`Hello ${name}` }',
"example.ts",
{
runtimeModule: "@palamedes/runtime",
keepSourceFallbacks: false,
},
);
console.log(result.code);The transform strips authored source messages from generated runtime calls and
Trans props by default. Set keepSourceFallbacks: true when the generated
code must render readable source text without a loaded catalog. The legacy
inverse option stripMessageField remains available for compatibility but is
deprecated.
Key Exports
transformPalamedesMacros(code, filename, options?)mightContainPalamedesMacros(code)findMacroImports(program)for compatibility with callers that already have an OXC ASTPALAMEDES_BUNDLER_TRANSFORM_INCLUDE, the shared Vite/Next default for.ts,.tsx,.js,.jsx,.mts,.cts,.mjs, and.cjssourcesPALAMEDES_MACRO_PACKAGESJS_MACROSJSX_MACROS
The root package also re-exports catalog-loader helpers from
@palamedes/transform/catalog-loader:
createCatalogLoaderResultrenderCatalogModulecreateCompileErrorMessagecreateDiagnosticMessagecreateMissingErrorMessageCatalogLoaderOptionsCatalogLoaderResultMissingCatalogMessage
renderCatalogModule() emits one defineCompiledCatalog() map. Constant
messages are strings; dynamic messages are renderer-independent functions with
module-hoisted choice branches. Invalid patterns become functions that delegate
to runtime pattern handling. The full Core entry preserves lazy-parser
diagnostics and source fallback; the parser-free entry reports the unsupported
pattern and returns its raw fallback. The helper delegates to the same native
Ferrocat-backed generator used by the first-party loaders; it does not maintain
a second ICU parser or generator.
Supported Macro Shapes
- tagged templates such as
t\...`` - descriptor calls such as
t({ message: "..." }) plural(...),select(...),selectOrdinal(...)<Trans>,<Plural>,<Select>,<SelectOrdinal>- the equivalent
jsx,jsxs, andjsxDEVcalls emitted throughremix/ui/jsx-runtimeorremix/ui/jsx-dev-runtime; helper and macro aliases are resolved by import binding identity
The eager t, plural, select, and selectOrdinal macros, plus
<Plural>, <Select>, and <SelectOrdinal>, must be syntactically inside a
function, method, or callback. This prevents translation from running as a
module-loading side effect before i18n activation. <Trans> may remain at
module scope because translation occurs when the component renders. Class field
initializers, including instance fields, are intentionally rejected; use a
method or getter instead.
Explicit author-facing id fields are intentionally not part of the supported end-state model.
Rich JSX children inside <Trans> are lowered to numeric component slots. For example,
<Trans><strong>A</strong> and <strong>B</strong></Trans> becomes a message shaped like
<0>A</0> and <1>B</1> with components={{ 0: <strong />, 1: <strong /> }}.
Related Packages
palamedes is part of the Ferramenta family — Rust-native developer tools that keep the APIs the ecosystem already knows.
Siblings: ferroni · ferriki · ferromark · ferrolex · ferrocat · ferrovia · ferralk · ferrugo.
License
MIT OR Apache-2.0 © 2026 Sebastian Software
