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/runtime

v1.25.0

Published

Palamedes runtime primitives for resolving the active i18n instance

Readme

@palamedes/runtime

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

Small runtime primitives for Palamedes-transformed code.

When Palamedes rewrites message macros, the generated code expects a getI18n() function. @palamedes/runtime provides that contract for browser code, server code, framework integrations, and backend request handlers.

When To Use This Package

Use @palamedes/runtime whenever transformed Palamedes code runs in your application. It is the small shared contract that keeps translated code from caring which framework is hosting it.

You typically install it together with:

Installation

pnpm add @palamedes/runtime

Minimal Example

import { createI18n } from "@palamedes/core";
import { setClientI18n } from "@palamedes/runtime";

const i18n = createI18n();
setClientI18n(i18n);

The public I18nInstance contract requires an initialized locale: string. Custom adapters registered with the client or server runtime must expose that property before registration.

Browser client registration also works in windowless Web Worker and Service Worker globals. Graph-split bootstrap modules can therefore initialize and resolve their client instance off the main thread.

For server-side rendering or server components, register a getter for the active request-local i18n instance:

import { setServerI18nGetter } from "@palamedes/runtime";

setServerI18nGetter(() => {
  return getRequestScopedI18n();
});

For Node server code, prefer the server-only helper subpath. It uses AsyncLocalStorage internally and registers the runtime getter once when the scope is created:

import { createI18n } from "@palamedes/core";
import { createServerI18nScope } from "@palamedes/runtime/server";

const serverI18n = createServerI18nScope<ReturnType<typeof createI18n>>();

serverI18n.activate(i18n);
renderTranslatedServerComponents();

await serverI18n.run(i18n, async () => {
  renderTranslatedRequestHandler();
});

All scopes created by this helper share the same runtime getter, so independently created scopes do not disconnect transformed getI18n() calls from the scope that was activated for the current async context. Framework adapters can also provide a stable request key for hosts that resume rendering from an earlier async context; application code should use the framework adapter rather than constructing that provider itself.

Next.js App Router applications must use createNextServerI18nScope() from @palamedes/next-plugin/server. A plain AsyncLocalStorage.enterWith() lifetime does not cover Next's separate RSC and Client Component server-render passes after suspension.

Backend Servers

The same runtime model also works in classic backend applications such as Hono, Express, or custom Node servers.

The important requirement is request-local access to the active i18n instance. The recommended pattern is @palamedes/runtime/server:

import { createI18n } from "@palamedes/core";
import { createServerI18nScope } from "@palamedes/runtime/server";

const serverI18n = createServerI18nScope<ReturnType<typeof createI18n>>();

Per request, resolve the locale from Accept-Language, cookies, session data, or the user profile. Use serverI18n.activate(i18n) only when the host preserves the current Node async context after the initializer returns. Use serverI18n.run(i18n, ...) for tightly scoped request-handler callbacks. Hosts with multi-pass rendering or suspension need a framework adapter with a stable request key; Next applications use @palamedes/next-plugin/server.

For a fuller walkthrough, including Hono and Express examples, see:

API

  • getI18n()
  • isServerEnvironment() classifies the current runtime consistently across Palamedes packages; browser workers count as client environments, while Cloudflare Workers that expose Cloudflare's documented navigator.userAgent marker count as a server runtime.
  • setClientI18n(i18n)
  • activateServerI18n(i18n)
  • setServerI18nGetter(getter)
  • resetI18nRuntime()
  • createServerI18nScope() from @palamedes/runtime/server for Node runtimes
    • scope.activate(i18n) binds an i18n instance to the current async context
    • scope.run(i18n, callback) runs a callback inside a scoped async context
    • scope.get() returns the current scoped i18n instance, if one is active
    • requestKeyProvider is an adapter-only escape hatch for a stable host render identity; its symbol ID makes repeat registration bounded during dev HMR

When a request key is available, scope.activate() updates the instance stored for that key. Multiple activations under the same key are last-write-wins, which matches hosts such as Next where one render has one active instance. scope.run() remains isolated to its callback and takes precedence over that request-key fallback.

The @palamedes/runtime/server implementation imports Node async_hooks. In non-Node bundles, the subpath resolves to a small fallback module that throws an actionable Node-only error when called.

Isomorphic SSR client-component bundles can use activateServerI18n(i18n) from the main entry point to enter an existing request scope without importing the Node-only subpath. The server entry point must first configure the shared scope with createServerI18nScope(). The helper does not make a shared i18n singleton request-safe, so pass a fresh request-local instance.

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