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

@palamedes/core-node

v1.25.0

Published

Thin Node.js wrapper around the Palamedes Rust core

Readme

@palamedes/core-node

npm version CI Sponsored by Sebastian Software License: MIT OR Apache-2.0

The Node.js wrapper around Palamedes' native core.

Use this package when you are building tooling on top of Palamedes and want direct access to the careful parts of the system: PO/FCL catalog updates, audits, metadata validation, .po parsing, MDX analysis, extraction, and macro transformation.

The public catalog model is source-string-first: message + context is the semantic identity, while compact lookup keys remain internal compile/runtime details.

When To Use This Package

Reach for @palamedes/core-node when you are:

  • building custom tooling around Palamedes
  • integrating the native transform or extractor outside the first-party plugins
  • working on Palamedes internals

If you are integrating Palamedes into an app, you usually want one of these instead:

Installation

pnpm add @palamedes/core-node

See Platform support before installing the native binding. It is the authoritative list of published targets, Linux libc variants, unsupported Node processes, and recovery steps.

Example

import {
  combineCatalogFiles,
  getNativeInfo,
  mergeCatalogFilesThreeWay,
  parsePo,
  updateCatalogFile,
} from "@palamedes/core-node";

const info = getNativeInfo();
const po = parsePo(`
msgid ""
msgstr ""
"Language: en\\n"
`);
updateCatalogFile({
  targetPath: "src/locales/en.po",
  locale: "en",
  sourceLocale: "en",
  clean: false,
  po: { lineBreaks: "off" },
  messages: [{ message: "Hello {name}", extractedComments: [], origins: [] }],
});
combineCatalogFiles({
  inputPaths: ["src/locales/de.po", "incoming/de.po"],
  outputPath: "src/locales/de.po",
  format: "po",
  sourceLocale: "en",
});
mergeCatalogFilesThreeWay({
  ancestorPath: "git/base/de.po",
  oursPath: "src/locales/de.po",
  theirsPath: "incoming/de.po",
  outputPath: "src/locales/de.po",
  format: "po",
  sourceLocale: "en",
  conflictStrategy: "useFirst",
});
combineCatalogFiles({
  inputPaths: ["src/locales/de.fcl", "incoming/de.fcl"],
  outputPath: "src/locales/de.fcl",
  format: "fcl",
  sourceLocale: "en",
});

console.log(info.palamedesVersion);
console.log(po.headers.Language);

Available APIs

  • getNativeInfo()
  • parsePo(source)
  • updateCatalogFile(request)
  • updateCatalogFileAsync(request, taskOptions?)
  • parseCatalog(request)
  • listTranslationCandidates(request)
  • applyTranslationPatches(request)
  • applyTranslationPatchesAsync(request, taskOptions?)
  • isTranslationPatchWriteError(error)
  • auditCatalogs(config, options?)
  • deriveMessageMetadata(message, context?)
  • normalizeMessageMetadata(input)
  • validateMessageMetadata(input)
  • combineCatalogs(request)
  • combineCatalogFiles(request)
  • mergeCatalogsThreeWay(request)
  • mergeCatalogFilesThreeWay(request)
  • compileCatalogArtifact(config, resourcePath)
  • compileCatalogArtifactAsync(config, resourcePath, taskOptions?)
  • compileCatalogArtifactSelected(config, resourcePath, compiledIds)
  • compileCatalogArtifactSelectedAsync(config, resourcePath, compiledIds, taskOptions?)
  • compileCatalogModule(config, resourcePath, options)
  • compileCatalogModuleAsync(config, resourcePath, options, taskOptions?)
  • renderCatalogModule(messages)
  • extractMessagesNative(source, filename, mdxOptions?)
  • analyzeSourceNative(source, filename, options?)
  • analyzeMdxNative(source, filename, options?)
  • extractCatalogMessagesFromFiles(request)
  • extractCatalogMessagesFromFilesAsync(request, taskOptions?)
  • transformMacrosNative(source, filename, options?)

analyzeMdxNative() and transformMacrosNative() omit authored source-message fallbacks by default. Pass keepSourceFallbacks: true when generated runtime code must retain them. stripMessageField remains a deprecated inverse option for macro-transform compatibility.

Catalog operations use Ferrocat for parsing, updates, audits, ICU authoring diagnostics, metadata validation, and deterministic combine workflows. That keeps custom tooling close to the same semantics used by the official CLI and framework plugins.

updateCatalogFile() accepts an optional PO output control through po: lineBreaks ("auto" or "off"). Catalog order is not configurable — Ferrocat sorts PO and FCL catalogs by message and then context using the CLDR root order that Intl.Collator("en-US") produces. PO options are rejected for FCL updates.

The wrapper exposes lowercase public format values ("po" and "fcl") while mapping to the native Ferrocat-backed API internally.

analyzeMdxNative uses the same FerroMark-backed semantic workflow as native catalog extraction. It returns extracted messages, structured source-ranged diagnostics, React or Solid JSX, compiled message IDs, and a source map.

analyzeSourceNative is the shared JS, TS, JSX, TSX, and MDX authoring entry point. It returns extracted messages plus deterministic diagnostics with a stable code, lowercase severity, filename, exact UTF-8 byte range, one-based line and Unicode-scalar column, actionable help, and an optional related range. The recommended placeholderOnly rule defaults to "warning"; the narrower emptyComponentOnly rule defaults to "off"; and the readability-oriented preferTransInJsx suggestion defaults to "info". All three accept "off", "info", "warning", or "error" through options.rules. The JSX rule never treats t as invalid and the initial diagnostic does not auto-fix imports or unsafe attribute, restricted-element, or non-render rewrites.

compileCatalogModule(config, resourcePath, options) is the direct module rendering API used by the first-party Vite, Next, and Remix .po loaders. Pass the artifact config, the resource path, and options such as locale, pseudoLocale, failOnMissing, and failOnCompileError. The generated module contains one map of constant strings and executable message functions lowered from Ferrocat's AST, so valid dynamic messages need neither ICU parsing nor AST interpretation in the browser.

Use the Async variants for file reads, catalog writes, and catalog compilation on a server or build-tool event loop. They preserve the synchronous result and error shapes, but schedule one owned operation on Node's shared libuv worker pool. The first-party Vite and Next loaders await these variants; the Remix synchronous module hook keeps the compatible synchronous API.

The six async APIs accept an optional { signal } task-options object. Aborting the signal rejects work that is still queued for a libuv worker with an AbortError; native work that has already started finishes normally. When custom tooling starts many independent operations, still limit its own concurrency instead of creating an unbounded Promise.all fan-out. The libuv pool is shared with other Node filesystem and native work; UV_THREADPOOL_SIZE remains Node's process-level control.

Concurrent compileCatalogArtifactSelectedAsync() calls for the same catalog and configuration are coordinated before they enter the worker pool. The first call performs an initial native build; callers that arrived while it was running wait in JavaScript and only enter native code after the cache is warm. If that initial build fails, waiting callers retry one at a time so cancellation or a selected-ID compilation error from one caller does not reject another. Independent catalogs can still compile concurrently.

This build coordination applies within one loaded JavaScript module instance. Loading both the CommonJS and ESM entry points, or loading multiple copies of the package, creates independent coordinators. The synchronous compileCatalogArtifactSelected() API also bypasses the JavaScript coordinator. If it races an in-flight native build for the same cache key, it can wait for that build and block the Node.js event loop. Event-loop-sensitive integrations should use the async API and avoid mixing package instances for concurrent same-key builds.

Async catalog mutations targeting the same resolved file are also serialized within one loaded JavaScript module instance, including calls across updateCatalogFileAsync and applyTranslationPatchesAsync. Mutations of different files can still run concurrently. Loading both package formats or multiple package copies creates independent mutation queues. Separate module instances, separate Node.js processes, and concurrent synchronous mutations must coordinate access themselves.

renderCatalogModule(messages) exposes that same canonical native generator for compatibility helpers and custom integrations that already have a compiled message map.

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

Sebastian Software

MIT OR Apache-2.0 © 2026 Sebastian Software