# nuxt-i18n-micro admits it costs 138 MB more than no i18n at all

> nuxt-i18n-micro is a Nuxt internationalization module that publishes its own benchmark table against @nuxtjs/i18n 10.6.0 and against a no-i18n baseline, and corrects an earlier version of that table in a footnote. The numbers say build time is a wash and the real difference is under load, and the project's willingness to subtract its own overhead is the most useful thing on the page.

**s00d/nuxt-i18n-micro** — Nuxt I18n Micro is a fast, simple, and lightweight internationalization (i18n) module for Nuxt

- Repository: https://github.com/s00d/nuxt-i18n-micro
- Website: https://s00d.github.io/nuxt-i18n-micro/
- Stars: 251 · Forks: 31
- Language: TypeScript
- License: MIT
- Published: 2026-08-27 · Updated: 2026-08-27 · Language: en
- Canonical page: https://hysenlabs.com/projects/s00d-nuxt-i18n-micro

## The footnote retracts an earlier number, and the baseline is a purpose-built fixture

Two things in the benchmark section tell you how much to trust the rest of it. The first is a correction. A note under the table states that the code bundle figure counts JavaScript and CSS only, excluding classified translation payloads including the other module's raw message chunks, and that older tables showing roughly 15 MB of code for version 10.6 were counting message chunks as application code. So a previous claim overstated the competitor's bundle by an order of magnitude, and the project says so in its own footnote rather than quietly issuing new numbers. The second is the baseline. The plain-nuxt row is not stock Nuxt: it is described as a minimal implementation created solely for benchmarking, loading data straight from JSON files with no i18n logic at all. That makes the no-i18n comparison a controlled experiment, which is the right way to isolate a module's cost, and it also means the baseline is not a number you will reproduce in your own application.

## Against no i18n at all, the module costs 138 MB of peak memory

The most useful line in the comparison is the one that subtracts the module from itself. Measured as a mean of three consecutive forced rebuilds, the baseline builds in 5.07 seconds at 859 MB peak, i18n-micro builds in 5.01 seconds at 997 MB, and the other module builds in 8.23 seconds at 1,292 MB. So the honest overhead statement for this module is roughly the same build time, about 0.22 MB more code, and 138 MB more peak memory than running no internationalization layer whatsoever. The competing module is quoted at 3.16 seconds more build time, 0.68 MB more code and 433 MB more peak memory against the same baseline. Two consequences follow. If your build is already slow for other reasons, 138 MB is unlikely to be the thing you feel. If you are chasing the gap to the other module, most of the win is build time and peak memory, not the code you ship.

## Under load is where the two modules actually diverge

The build-time table is close to a tie, so the stress numbers carry the argument. Running the same fixture through Artillery with the documented load profile, the baseline averages 2,087 ms per response at 102 requests per second, this module averages 583 ms at 230 requests per second, and the competing module averages 1,268 ms at 126 requests per second. Set against the other module directly, that is 685 ms faster average response and 104 more requests per second, on the project's own hardware with the real distribution build. Two cautions belong next to those numbers. The first is that the harness is the author's, run on one machine, and the comparison is only as good as the fixture both projects are pointed at. The second is that the baseline being slowest under load is expected and is not a claim about this module, since a no-i18n application has nothing to translate. The meaningful comparison is the two i18n modules, and on that comparison the gap is real and large.

## Route strategy is decided at build time, path strategy at runtime

Locale prefixing is split across two separate packages, and the split is the architectural idea rather than an implementation detail. `@i18n-micro/route-strategy` handles locale prefixes at build time, and `@i18n-micro/path-strategy` handles them at runtime. Four strategy names are available: prefix, no_prefix, prefix_except_default and prefix_and_default. The naming encodes the two axes you would otherwise configure separately, since a strategy decides both whether the default locale appears in the URL and whether every other locale does. The stated design goal behind the minimalist core is a single Nuxt module plus a small set of runtime plugins, which is a plausible reason the strategy logic is factored out rather than fused in. If you are migrating from a module that treats prefixing as a boolean, the four names are the vocabulary you will be choosing between, and prefix_except_default is the one that changes the most URLs.

## JSON only, and missing page files are generated in dev and nowhere else

The translation loading story is deliberately narrow, and one clause in it deserves attention. Only JSON files are supported, with translations split between a global file for common text such as menus and page-specific files. Those page files are auto-generated in the dev mode if they are not present. That is a genuine convenience, because it removes the first-run error of a missing translation, and it has an equally genuine edge: the generation is scoped to dev, so a page that was only ever exercised locally can reach a production build without the file it relied on. The format restriction is the other half. YAML, in-JavaScript and in-template translation files are not options, so a codebase that keeps copy next to components has to restructure or stay where it is. The configuration surface in the quick setup reflects this: a list of locales carrying a code, an ISO tag and a text direction, a default locale, a translation directory, and a metadata switch.

## Setup is one install and one config block, with direction per locale

There is no init command and no generator. The install is:

```bash
npm install nuxt-i18n-micro
```

After that the module goes in the modules array and everything else lives under an `i18n` key. The example configuration is short enough to read in full, and each field earns its place:

```typescript
export default defineNuxtConfig({
  modules: [
    'nuxt-i18n-micro',
  ],
  i18n: {
    locales: [
      { code: 'en', iso: 'en-US', dir: 'ltr' },
      { code: 'fr', iso: 'fr-FR', dir: 'ltr' },
      { code: 'ar', iso: 'ar-SA', dir: 'rtl' },
    ],
    defaultLocale: 'en',
    translationDir: 'locales',
    meta: true,
  },
})
```

Three things are worth pulling out of that block. A locale carries three separate values, a short code used in URLs, a full ISO tag, and a text direction, so Arabic is declared right-to-left in config rather than detected at runtime. The translation directory is a single path that holds both the global file and the per-page files, which is what keeps the JSON-only rule workable. And the metadata switch is what enables the search-engine side, with the documentation carrying dedicated pages for the SEO guide and the components reference, plus a migration guide and a layers guide for multi-package setups.

## Four internal subpaths all resolve to one declaration file

The published package keeps a small surface and an unusual one. It ships two things, a dist directory and a single declaration file, and the entry point is an ESM module. The interesting structure is in the subpath exports, where four internal names all point at that same declaration file rather than at four separate modules: a plural helper, a strategy helper, a config helper and a payload-source helper. Each is exposed twice, once through the types-version map so TypeScript resolves the types, and once through the import map so a bundler resolves the runtime value. The declared intent is a root-only public API, with the internals available under their own namespaced paths rather than exposed as top-level exports. For a consumer, the practical effect is that the four subpaths are for internal use and may move between minor versions, while the root export is the contract. The repository also keeps four separate vitest configurations, one each for unit, integration, end-to-end and package tests, which is what a module with runtime plugins and a playground needs to keep its own test surface honest.

## Conclusion

nuxt-i18n-micro fits a Nuxt application that is translation-heavy and serving real traffic, since the difference between the two modules is build cost and behaviour under load rather than features, and the module is deliberately narrow. It does not fit a project that needs YAML, in-JS or in-Vue translation files, because JSON is the only supported format. Before you commit, read the performance methodology page rather than the table, check that your build is not already fast enough for the difference to matter, and decide deliberately whether you want the dev-mode auto-generation of missing translation files, since that convenience behaves differently outside dev.

## FAQ

### How do I install and configure nuxt-i18n-micro?

Run `npm install nuxt-i18n-micro`, then add it to the modules array in `nuxt.config.ts` under an `i18n` key with a locales list, a default locale, a translation directory and the metadata switch. Each locale entry carries a code, an ISO tag and a text direction, so a right-to-left locale is declared as `dir: 'rtl'`.

### What translation file formats does nuxt-i18n-micro support?

Only JSON. Translations are split between a global file for common text and page-specific files, and missing page files are auto-generated in dev mode if not present, but that generation does not apply outside dev.

### How does nuxt-i18n-micro compare to @nuxtjs/i18n on build time?

In the project's own benchmark, a mean of three forced rebuilds, i18n-micro builds in 5.01s against 8.23s for @nuxtjs/i18n 10.6.0, with a no-i18n baseline at 5.07s. The comparison against the baseline is the honest one: about the same build time, 0.22 MB more code and 138 MB more peak memory.

### What are the locale prefix strategies in nuxt-i18n-micro?

Four names, prefix, no_prefix, prefix_except_default and prefix_and_default. They are split across two packages: `@i18n-micro/route-strategy` handles locale prefixes at build time and `@i18n-micro/path-strategy` handles them at runtime.

### How much faster is nuxt-i18n-micro under load?

The project's Artillery stress test reports 583 ms average response at 230 requests per second, against 1,268 ms and 126 requests per second for @nuxtjs/i18n 10.6.0. That is 685 ms faster average response and 104 more requests per second, on the author's own hardware and fixture.

## Sources

- [Official documentation](https://s00d.github.io/nuxt-i18n-micro/)
- [Official README](https://github.com/s00d/nuxt-i18n-micro#readme)
- [Project repository](https://github.com/s00d/nuxt-i18n-micro)
- [Release notes](https://github.com/s00d/nuxt-i18n-micro/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/s00d-nuxt-i18n-micro
