Requirements
- Node.js ≥ 22.6. Titah uses
node:sqlite, which needs a recent Node. It is developed on v26. - Linux or macOS. Windows is not supported in v1 — see Architecture. The code stays platform-neutral, so Windows later is roughly a day of work, not a rewrite.
- A model provider. Anything OpenAI-compatible, an Anthropic key, or a local endpoint such as Ollama or LM Studio.
Check your Node version first:
node --version # must be >= 22.6
Route 1 — curl (recommended)
curl -fsSL https://titah.dev/install | bash
The installer:
- Checks that you are on Linux or macOS.
- Checks that
node --versionis ≥ 22.6, and that npm is present. - Runs
npm install -g titah-code, and confirmstitahactually landed on yourPATHafterwards. - Runs
titah init— detecting a provider, running an interactive wizard only for what it genuinely cannot work out.
To skip the wizard entirely (good for scripts and CI):
curl -fsSL https://titah.dev/install | bash -s -- -y
!!! note “It exits 0 once titah is installed, even if setup did not finish”
Installing and configuring are different jobs, and this script does the
first. On a machine with no provider key yet, step 4 cannot finish — so it
says so and still exits 0, rather than failing a Dockerfile build over a
step it was never going to be able to complete. Finish it later with
titah init.
A non-zero exit means the **install** failed: the wrong OS, Node too old,
npm missing, or npm unable to write to its global prefix. In that last case
the script prints npm's own error, names the prefix, and gives you the exact
command to run — it does not assume every failure is a permissions problem.
If it fails
The script prints what npm actually said before it explains anything, so start by reading that. Two failures account for nearly all of them:
| Symptom | Cause |
|---|---|
EACCES / permission denied writing to the npm prefix | npm’s global directory needs root. The script offers sudo when it can prompt, and otherwise gives you the command; the npm guide fixes it permanently |
titah is not on PATH after install | npm installed it somewhere not on your PATH. The script prints the directory — add it |
Route 2 — npx, no permanent install
npx titah-code init # detect a provider, write the config
npx titah-code # open the TUI
npx fetches the package on demand, runs it, and leaves nothing permanent
behind except the config init wrote. Convenient when you want to try Titah
before committing to a global install.
Route 3 — global npm install
npm install -g titah-code
titah init
titah
!!! warning “The package and the command have different names”
The npm package is titah-code; the command it puts on your PATH is
titah, declared in the package’s bin field. npm install -g titah
installs nothing — that name is not ours.
Route 4 — from source
git clone https://github.com/titah-dev/titah.git
cd titah
npm install
npm run build
node dist/cli.js doctor
node dist/cli.js # open the TUI
!!! warning “The TUI requires a build”
Node runs .ts files directly but not .tsx — JSX is not stripped.
Headless commands (run, serve, doctor, …) still run straight from
source with node src/cli.ts; the TUI only runs from dist/.
What titah init actually does
init exists because telling someone to write a provider block with npm,
baseURL and a models map from scratch is the wall that makes people give up
in the first minute.
It runs in this order:
- Reads the environment —
ANTHROPIC_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY. - Probes local endpoints — Ollama and LM Studio on their conventional localhost ports.
- Asks only about what it genuinely cannot work out on its own.
curl -fsSL https://titah.dev/install | bash # interactive where it has to be
curl -fsSL https://titah.dev/install | bash -s -- -y # take the first thing found, no dialog
Or directly, once titah is already installed:
titah init # interactive where it has to be
titah init -y # take the first thing found, no dialog
-y suits scripts and Dockerfiles, where a wizard would hang forever waiting
for an answer nobody is there to give.
The default model is always explicit in the config. If none is chosen, Titah shows a picker rather than guessing — a silently guessed model is a bill you did not agree to.
Verify the install
titah doctor
titah doctor --probe # also test network reachability per provider
doctor reports your environment, config file locations, the merged config
(redacted), which credentials resolved and from where, which external agents
were detected, the skills it found per namespace, and every model missing a
declared contextWindow.
It is the first thing to run when something is not behaving, and the first thing to paste into a bug report.
Where things end up
| Path | Holds |
|---|---|
~/.config/titah/titah.json | Global config |
./titah.json | Project config, merged over the global one |
~/.local/share/titah/auth.json | Provider credentials, mode 0600 |
~/.local/share/titah/account.json | Your Titah account token, mode 0600 |
~/.local/share/titah/ | Sessions database, tool output, snapshots, logs |
titah config path prints all of them for the machine you are on — the
directories follow XDG_CONFIG_HOME and XDG_DATA_HOME when those are set.
Nothing is written outside those paths, and your project’s own .git is never
touched — see Permissions & undo.
Uninstall
npm uninstall -g titah-code
rm -rf ~/.config/titah ~/.local/share/titah
The second line is the one that actually reclaims disk. Removing the package alone leaves sessions and snapshots behind.