Skip to main content
Glama

The idea

Most i18n tools ask you to invent a key for every sentence, write it in a file per language and keep the files in step with the code by hand. Verbaly turns that around:

// with key files: name it, write it in en.json, es.json, pt.json, keep them in sync
t('dashboard.welcome_back', { name });

// with Verbaly: write the sentence where it is used
t`Welcome back, ${name}`;

// and the compiler writes a stable key and a typed call for you
t('ESsQIvlA', { name });

The runtime that ships is 3.35 KB gzip with zero dependencies, measured on every release by a gate in this repo (pnpm --filter verbaly size).

Related MCP server: i1n

Quick start

pnpm add verbaly @verbaly/vite
pnpm add -D @verbaly/compiler   # the verbaly command: init, extract, check
npx verbaly init
// vite.config.ts
import verbaly from '@verbaly/vite';

export default { plugins: [verbaly()] };
// anywhere in your app: extracted and typed on save
import { t, setLocale } from 'verbaly/app';

t`Hello ${name}`;
await setLocale('es'); // loads only the Spanish module

verbaly/app is your project's own module: the plugin writes it from your config, with your languages and catalogs already in it. Next.js, Nuxt, SvelteKit and Astro have their own one-line setup: pick yours in the row above, or read the full docs at https://verbaly-web.vercel.app/docs.

Why Verbaly

Review translations in a panel

npx verbaly-studio

Studio serves your project over localhost: what is missing, what is broken, what a machine wrote and where each text lives in your code. Your JSON files are the database and git is the history, a save runs the same validations as verbaly check, and it never edits your source text.

How it compares

Verbaly

i18next

Lingui

Paraglide

typesafe-i18n

Type-safe keys & params

✅ inferred from text

plugin/manual

partial

✅

✅

Runtime size (gzip)

3.35KB, zero deps

13.6KB (19.0 +react)

2.2KB (3.3 +react)

compiled

1.2KB

Setup

1 Vite plugin

heavy config

macros + Babel/SWC

inlang project

generator

Key maintenance

none, extracted

by hand

extract → compile step

by hand

by hand

Dynamic / CMS content

✅ real runtime path

✅

✅

⚠️ weak

✅

Plain HTML (no framework)

✅ DOM interpreter

❌

❌

❌

❌

Missing-translation gate

✅ fails CI only

runtime warning

CI step

✅

❌

Broken-translation gate

✅ fails CI only

❌

❌

❌

❌

Catalog format

plain JSON

JSON

PO/JSON

inlang format

TS files

Sizes are min+gzip of each library's main entry with React external, measured with the same method on 2026-10-15.

Coding agents

claude mcp add verbaly -- npx -y @verbaly/mcp

The MCP server gives your agent the whole cycle as tools, with structured output and resources to read your config and catalogs. Machine translations stay drafts until a person approves them (verbaly review --approve, or Studio): approving is deliberately not a tool. The Agent Skill teaches the write, extract, check and translate cycle (npx degit AronSoto/verbaly/skills/verbaly .claude/skills/verbaly), and the docs publish llms.txt.

Packages

Package

What it is

verbaly

The runtime: t, Intl formats, locale helpers and the DOM interpreter

@verbaly/compiler

Extraction, typed codegen, the gate and the verbaly command

@verbaly/vite · @verbaly/unplugin

Bundler plugins: Vite, and webpack, Rollup, esbuild and Rspack

@verbaly/react · @verbaly/vue · @verbaly/svelte

Framework adapters: hooks or composables plus <Trans>

@verbaly/next · @verbaly/nuxt · @verbaly/sveltekit

Server rendering: the language per request, hydration with no flash

@verbaly/astro

Astro integration: .astro extraction and a static build per language

@verbaly/mcp

MCP server: the translation cycle as tools for an agent

@verbaly/studio

The local review panel above

All of them share one version number, and every release is published from CI with npm provenance.

Generated keys are hashes, so t('a1B2c3D4') in a diff tells you nothing. The i18n-ally extension shows the real text inline once you point it at your catalogs. Two files, no Verbaly config changes:

.vscode/settings.json

{
  "i18n-ally.localesPaths": ["locales"],
  "i18n-ally.keystyle": "flat",
  "i18n-ally.sourceLanguage": "en",
  "i18n-ally.displayLanguage": "en"
}

.vscode/i18n-ally-custom-framework.yml

languageIds:
  - javascript
  - typescript
  - javascriptreact
  - typescriptreact
  - vue
  - svelte
  - astro
usageMatchRegex:
  - "[^\\w\\d]t\\(\\s*['\"`]({key})['\"`]"
monopoly: true

keystyle has to match your catalogs: flat for dotted keys, nested for groups. Use the extension for reading, not writing: its extract and rename actions assume you own the keys, and here the compiler does.

Development

pnpm install
pnpm build      # tsdown: ESM + CJS + .d.ts
pnpm test       # each package's suite
pnpm typecheck
pnpm --filter verbaly bench   # the hot path against i18next

Verbaly is 0.x: the API can still change between minor versions, and every change is in the changelog. Contributions are welcome: see CONTRIBUTING.md.

Feedback

  • Something broke or surprised you: open a bug. A minimal snippet is enough.

  • Something felt like friction: tell us what. The roadmap follows real use.

  • It just works: a star or a mention helps others find it.

Sponsor

Verbaly is MIT-licensed, dependency-free and built independently. If it saves you time, sponsoring it funds the road to 1.0: more integrations, faster releases and long-term maintenance.

License

MIT © Aron Soto · @AronSoto

Related MCP Connectors

Related MCP Servers