Skip to content
v0.72.0latest

Write natural text. Ship type-safe translations.

The compiler extracts your messages, generates the types and splits bundles per locale. Every build lists a missing translation and your CI stops it, so it never reaches your users.

Integrations
~3 KBruntime
13packages
MITlicense
i18n that feels like zero config

Why Verbaly

Four things the compiler does for you, each one running right here.

Zero config, actually

One Vite plugin. No giant init(), no Babel macros, no proprietary formats. Catalogs are plain JSON you can take anywhere.

The keys are yours

By default you never write one. Name them when you want to read them, or declare them in a module when they are a contract with something outside your app, and Verbaly checks every one against your catalog. The text never changes.

Types from your messages

The text itself declares its params, so if you forget one TypeScript stops you.

Plain HTML, first-class

No framework? The DOM interpreter hydrates data-verbaly nodes, re-renders on locale switch and watches new elements.

Same job, less machinery

An honest look against the tools you'd otherwise reach for. It shows where Verbaly wins, and where the others are fine too.

FeatureVerbalyVerbalyi18nextLinguiParaglide
Type-safe keys & paramsInferred from your textPlugin / manualPartialYes
Runtime size (gzip)3.31 KB, zero deps (6.13 with DOM + urls)13.6 KB (23 with React)2 KB (4 with React)compiled, no shared runtime
Key maintenanceNone, auto-extractedBy handExtract → compile stepBy hand
Dynamic / CMS contentReal runtime pathYesYesWeak
Plain HTML (no framework)DOM interpreter———
Missing translationsFails CI, every build lists itRuntime warningCI stepBuild fails
Broken translationsFails CI, every build lists it———
Catalog formatPlain JSONJSONPO / JSONinlang format
Coding agentsMCP server + skill—Skill—
VerbalyVerbaly
Type-safe keys & params
Inferred from your text
Runtime size (gzip)
3.31 KB, zero deps (6.13 with DOM + urls)
Key maintenance
None, auto-extracted
Dynamic / CMS content
Real runtime path
Plain HTML (no framework)
DOM interpreter
Missing translations
Fails CI, every build lists it
Broken translations
Fails CI, every build lists it
Catalog format
Plain JSON
Coding agents
MCP server + skill
i18next
Type-safe keys & params
Plugin / manual
Runtime size (gzip)
13.6 KB (23 with React)
Key maintenance
By hand
Dynamic / CMS content
Yes
Plain HTML (no framework)
—
Missing translations
Runtime warning
Broken translations
—
Catalog format
JSON
Coding agents
—
Lingui
Type-safe keys & params
Partial
Runtime size (gzip)
2 KB (4 with React)
Key maintenance
Extract → compile step
Dynamic / CMS content
Yes
Plain HTML (no framework)
—
Missing translations
CI step
Broken translations
—
Catalog format
PO / JSON
Coding agents
Skill
Paraglide
Type-safe keys & params
Yes
Runtime size (gzip)
compiled, no shared runtime
Key maintenance
By hand
Dynamic / CMS content
Weak
Plain HTML (no framework)
—
Missing translations
Build fails
Broken translations
—
Catalog format
inlang format
Coding agents
—

From words to shipped locales

Three steps and a guardrail, or let verbaly init scaffold it in one command. No key files written by hand: the compiler does the boring parts while you keep writing product copy.

  1. Install

    One command, three packages: the runtime, the plugin and the command.

     pnpm add verbaly @verbaly/vite @verbaly/compiler
  2. Add the plugin

    Point it at the locale you write in.

    vite.config.ts
    import verbaly from '@verbaly/vite';
    
    export default { plugins: [verbaly({ sourceLocale: 'es' })] };
  3. Write text, not keys

    Keys, types and catalogs: generated.

    src/app.ts
    import { t, setLocale } from 'virtual:verbaly';
    
    t`Hola ${name}`;      // keys, types & catalogs: generated
    await setLocale('pt'); // lazy-loads its chunk
  4. Let CI guard it

    Exits 1 while any locale is incomplete, so untranslated text never ships.

    .github/workflows/ci.yml
    - run: npx verbaly check  # exits 1 on a missing or broken translation

Your first translated page, in five minutes.

Install, add the plugin and write text. Verbaly extracts the messages, writes the types and loads each language when someone asks for it.

Get started

Already have catalogs? Open them in Studio

Copied to clipboard