skills/cli/SKILL.md
Extract source strings, generate locale files, and remove unused keys for Better Translate projects.
npx skillsauth add jralvarenga/better-translate cliInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this guide when you want the CLI to manage locale files for you, or when you want to write source strings directly in code without naming keys by hand.
bt extract — scans your source files for t("...", { bt: true }) calls, adds keys to your source locale JSON, and rewrites those calls to plain key stringsbt generate — reads your source locale file and calls an AI model to create translated versions for every other localebt purge — scans your codebase for translation keys that are no longer referenced in any t("...") call and removes them from all locale filesnpm install -D @better-translate/cli ollama-ai-provider-v2
Create src/messages/en.json:
{}
An empty object is fine. bt extract will populate it.
Create better-translate.config.ts:
import { createOllama } from "ollama-ai-provider-v2";
import { defineConfig } from "@better-translate/cli/config";
const ollama = createOllama({
baseURL: process.env.OLLAMA_BASE_URL ?? "http://localhost:11434/api",
});
export default defineConfig({
sourceLocale: "en",
locales: ["es", "fr"],
model: ollama("qwen3:4b"),
messages: {
entry: "./src/messages/en.json",
},
});
If you use Ollama, install ollama-ai-provider-v2. If you use a hosted provider, install the matching AI SDK provider package.
The CLI stays provider-agnostic. Swap ollama(...) for any other AI SDK provider model if you use a different provider.
In any TypeScript or TSX file, write source text directly using { bt: true }:
t("Hello world", { bt: true });
t("Hello {name}", { bt: true, params: { name: "" } });
npx bt extract
The CLI automatically finds better-translate.config.ts in the project root. --config is only needed if the config file is in a non-standard location.
After this runs, the source locale file gains new keys and the original t() calls are rewritten:
// before
t("Hello world", { bt: true });
// after
t("components.header.helloWorld");
The namespace prefix (components.header) comes from the source file path. bt: true is removed. Other options like params are preserved.
npx bt generate
This creates one translated JSON file per locale next to the source file.
If markdown.rootDir is configured and the run would create or overwrite translated .md or .mdx files, the CLI asks for confirmation. Pass --yes or -y to skip:
npx bt generate --yes
npx bt purge
This finds translation keys that no longer appear in any t("...") call and removes them from all locale files. It asks you to confirm each key before removing it:
? Purge unused key "home.oldTitle"? (y/N) y
? Purge unused key "sidebar.legacy"? (y/N) n
Type y to remove a key, n (or just Enter) to keep it.
To remove all unused keys at once without prompting:
npx bt purge --yes
To preview what would be removed without making changes:
npx bt purge --dry-run
Dynamic keys: If code uses a dynamic key like t(`section.${id}`), the CLI cannot statically resolve it. It will warn you, protect keys sharing the detected prefix, or mark the key unsafe and skip it rather than silently deleting something that may still be in use.
| Command | Flag | Description |
|---|---|---|
| bt extract | | Scan for bt: true calls, sync source locale, rewrite calls |
| | --config <path> | Path to config file (default: auto-detected) |
| | --dry-run | Preview changes without writing |
| | --max-length <n> | Max segment length for generated key names |
| bt generate | | Translate source locale into all target locale files |
| | --config <path> | Path to config file |
| | --dry-run | Preview changes without writing |
| | --yes, -y | Skip confirmation for markdown file writes |
| bt purge | | Remove unused translation keys from all locale files |
| | --config <path> | Path to config file |
| | --dry-run | Preview which keys would be removed without writing |
| | --yes, -y | Remove all unused keys without prompting |
Always run bt extract before bt generate. Extract populates the source file; generate reads it.
After removing old features or refactoring key usage, run bt purge to clean up orphaned keys across all locale files.
The CLI only manages files. Autocomplete at runtime still comes from the shared exported translator you create in @better-translate/core.
translatorThe CLI only manages files. You still need a runtime package to use them.
@better-translate/core to load and use locale files at runtime@better-translate/react for React components@better-translate/nextjs for Next.js routingexamples/nextjs-example — Next.js App Router with generated locale filesexamples/react-vite-example — React SPA with generated locale filesexamples/core-elysia-example — plain TypeScript/Node.js setupdocumentation
Repository map for finding Better Translate packages, docs, and examples.
tools
Snapshot of the current public Better Translate package and adapter surface.
documentation
Right-to-left locale configuration guide for Better Translate.
development
React and Expo integration guide for Better Translate providers, hooks, and typed translation access.