← Back to archive

Repo of the Day

opral/paraglide-js

Published: Nov 4, 2026

Open repository ↗

Compiler-based i18n library that emits tree-shakable translations, leading to up to 70% smaller bundle sizes

Summary

Paraglide JS is a compiler-first i18n library that turns translation files into typed ESM message functions before an application ships. It is designed for Vite-based applications, with documented integrations for React, TanStack Start, SvelteKit, React Router, Astro, Vue, Solid, and vanilla JavaScript/TypeScript.

What it is useful for

Paraglide fits projects where translation keys are known at build time and engineers want type checking and bundler-level tree shaking. For example, messages/en.json can contain "greeting": "Hello {name}!"; application code then calls m.greeting({ name: "Ada" }). The generated function provides autocomplete and compile-time checking for message keys and parameters.

It is also relevant when a product needs URL-based locale detection, localized paths, or server-side rendering. Paraglide’s middleware uses AsyncLocalStorage to keep getLocale() and message calls request-scoped during concurrent requests. The localizeUrl() helper can turn /about into /de/ueber, while deLocalizeUrl() maps that browser-facing URL back to the canonical route.

The formatting system supports plural rules, numbers, dates, relative time, and ICU MessageFormat 1 through a plugin. Existing i18next, JSON, XLIFF, or default inlang files can be compiled, allowing teams to change application code incrementally.

The main boundary is build-time discovery: dynamic menus and CMS entries need explicit mappings to generated functions, or content returned already localized. The README also says there is no fixed bundle-size saving, and compilation alone does not guarantee a faster page. Default output retains all configured locales for every used message; per-locale builds are opt-in and experimental.

How engineers can use it

Start with the documented initializer:

npx @inlang/paraglide-js init

For coding agents or CI, the README documents:

npx @inlang/paraglide-js init --yes --outdir ./src/paraglide --lint eslint

This creates message files, configures the bundler, and generates typed message functions. Existing inlang projects are reused; dirty Git trees require --allow-dirty.

For React with Vite, configure the compiler as shown in the README:

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { paraglideVitePlugin } from "@inlang/paraglide-js";

export default defineConfig({
  plugins: [
    react(),
    paraglideVitePlugin({
      project: "./project.inlang",
      outdir: "./src/paraglide",
      emitTsDeclarations: true,
    }),
  ],
});

Then import the generated code:

import { m } from "./paraglide/messages.js";
import { locales, setLocale } from "./paraglide/runtime.js";

const text = m.greeting({ name: "Ada" });

By default, setLocale(locale) performs a document navigation, using the localized URL when URL routing is enabled. Framework-specific setup is not fully spelled out in the README, so follow its linked React, Vite, SvelteKit, Astro, or other integration guide for the chosen stack.