Create your first project
The Quick Start runs kapi ad-hoc — one command,
one file, flags for everything. That's the right shape for a one-off. For content
you localize more than once — a repository, a product's strings, a docs set —
a .kapi project is the working model worth adopting: you capture the
languages, content patterns, and flows in a committed recipe once, then drive
everything through short commands with no repeated flags.
This page walks the smallest end-to-end loop: init → read the recipe → run a
flow → merge the files out.
Loading the walkthrough…
1. Initialize the project
Run kapi init in the directory you want to localize. It scaffolds a
<dir-name>.kapi recipe and an adjacent .kapi/ state directory:
kapi init --source-locale en --target-locale fr,de
Initialized kapi project "my-app"
recipe: my-app.kapi
state: .kapi
The recipe is committed; the .kapi/ state directory is regenerable and belongs
in .gitignore. A fresh init declares your languages but no content yet —
that's the next step.
2. Declare the content to localize
Tell the project which files to translate with kapi add — a glob, plus the
format (auto-detected if you omit it):
kapi add "src/locales/en/*.json"
Each kapi add appends a content entry to the recipe; kapi rm removes one and
kapi ls lists the files the project currently tracks (add --stats for per-file
block and word counts):
kapi ls
If your strings live in a known stack's i18n catalogs, skip the manual add and
let kapi init --framework <stack> (for example react-i18next, nextjs,
flutter) pre-fill the content mapping for you — see
kapi presets list --framework.
3. Read the recipe
The <dir-name>.kapi recipe is a portable YAML document. A minimal one declares
its languages, the content globs to localize, and the flows to run:
version: v1
name: my-app
defaults:
source_language: en
target_languages: [fr, de]
content:
- path: "src/locales/en/*.json"
target: "src/locales/{lang}"
flows:
translate:
steps:
- tool: tm-leverage
- tool: ai-translate
kapi add wrote the content entry's source path; the format is auto-detected
per file. The optional target — with the {lang} placeholder — tells merge
where each locale's files go. Here it names a directory, so each matched file is
mirrored under the per-language folder (src/locales/en/app.json →
src/locales/fr/app.json); set it for a custom layout (or let --framework fill
it), otherwise kapi defaults to a locale-suffixed path beside the source. For a
custom layout use tokens like {name}/{ext} — see the
project file reference.
defaults carries the
source and target languages every command inherits, and flows names reusable
tool chains. See the project file reference for the
full schema.
4. Run a flow
From anywhere inside the project tree, run a flow by name:
kapi run translate
kapi discovers the nearest recipe by walking up the directory tree (like git),
resolves the project's languages and content, and runs the flow. In a project, a
run is process-only — it commits results to the project store
(.kapi/cache/blocks.db) rather than writing files directly. That keeps repeated
runs cheap and lets the store accumulate translation memory and overlays as you
work.
5. Merge the files out
When you're ready to materialize the localized files, merge writes them to the
targets declared in the recipe:
kapi merge
This replays the stored translations onto each source and writes
src/locales/fr/*.json, src/locales/de/*.json, and so on — no flags, because
the recipe already says where each locale goes.
Inspect a project
The lab below is a project, interactive. Pick a sample, step through a declared flow, and watch the recipe, the per-locale state, and the output files update:
Why project mode
Project mode trades a one-time init for less repetition and more memory:
- Defaults captured once. Source and target languages, content globs, and
flow definitions live in the recipe. You stop passing
--source-lang,--target-lang, and-i/-oon every command. - Translation memory accumulates. The project store keeps a TM and termbase that every run reads and writes, so each pass recycles the last one's work.
- Git-style discovery. Run
kapifrom any subdirectory and it finds the project automatically — no-pflag, no cwd dance. - Portable and shareable. The recipe is a committed YAML file; a teammate who clones the repository runs the same flows with the same configuration.
Ad-hoc runs stay available for one-offs, scripting, and CI — the two are the same commands over a different binding (where content enters and leaves). See Modes & bindings for the full model.
Next
- Modes & bindings — the source/sink binding model and when to mix ad-hoc and project runs.
- Interchange — XLIFF, PO, and your TMS — extract a project to bilingual files for vendor or human translation, then merge back.
- Project file reference — the full
.kapirecipe schema and discovery rules.