stacktora
v0.16.2
Published
Keep your project's dev-environment files in sync with its stack recipe (stacktora.json).
Maintainers
Readme
stacktora
Keep your project's dev-environment files in sync with its stack recipe.
Stacktora generates a complete, runnable dev environment (docker-compose.yml, Makefile, CI, and more) from a stack you define. The CLI lets you regenerate those files locally from the recipe committed to your repo — so when image versions or best practices move, your environment doesn't drift.
Install
npm install -g stacktora
# or run without installing:
npx stacktora <command>How it works
Every project Stacktora generates includes a stacktora.json — the stack recipe (runtime, datastores, services, ports, options). The CLI reads it and regenerates the project's files using the exact same engine as the web app at stacktora.com. No account or network needed; it runs fully offline.
Stacktora always looks for stacktora.json in the current directory automatically — it is never passed as a command-line argument. Run every command from the same folder the file lives in: stacktora sync, not stacktora sync stacktora.json.
Commands
stacktora sync # regenerate all files from stacktora.json
stacktora check # show which files would change, without writing (drift detection)
stacktora plan # like check, but shows the actual line-by-line diff for each changed file
stacktora doctor # diagnose common local problems — Docker, port conflicts, missing .env keys, runtime mismatch
stacktora status # show live container health (docker compose ps) for the stack running here
stacktora recipes # list curated starting recipes bundled with the CLI
stacktora install # write a curated recipe as your stacktora.json — e.g. `stacktora install nextjs`
stacktora audit # check stacktora.json against company.stacktora.json policy, if one exists
stacktora init # create a starter stacktora.json in the current directory
stacktora helpAdd --json to check, plan, doctor, status, recipes, or audit for structured, machine-readable output — built for CI pipelines and AI agents that need to act on the result programmatically rather than parse colored terminal text. Exit code is still 0 for clean / 1 for issues found either way.
Editor autocomplete
Every stacktora.json this CLI writes includes a $schema field pointing at a published JSON Schema. Most editors (VS Code included) pick this up automatically — real autocomplete, and inline validation that catches things like an invalid datastore id before you ever run sync.
Recipes
stacktora recipes lists curated starting stacks bundled with the CLI — the same ones used by the templates gallery at stacktora.com, so there's exactly one place these are defined. stacktora install <id> writes one as your local stacktora.json, including runtime-correct defaults (package manager, linter, formatter, port) — installing the Django recipe gives you pip/ruff/black, not leftover Node.js tooling.
stacktora recipes
stacktora install django
stacktora syncRefuses to run if a stacktora.json already exists in the current directory, so it never silently overwrites your recipe.
Custom recipes
Drop your own recipe files in .stacktora/recipes/*.json and stacktora recipes / stacktora install pick them up automatically, listed first, ahead of the bundled ones. This is the natural way for a team to standardize: commit a recipe to the repo everyone works in, and any developer gets it with stacktora install <name>.
Each file needs a stack field — the same shape stacktora.json itself uses:
{
"name": "Acme Standard API",
"desc": "Our org's standard Node + Postgres + Redis baseline",
"stack": {
"runtime": "node", "version": "22",
"datastores": ["postgres", "redis"], "services": [],
"tools": { "packageManager": "pnpm", "linter": "eslint", "formatter": "prettier" },
"config": { "appName": "acme-api", "appPort": 4000, "hotReload": true, "seed": true, "healthGate": true, "worker": false, "env": [], "outputs": {} }
}
}The filename (minus .json) becomes the id — .stacktora/recipes/acme-api.json installs as stacktora install acme-api. A custom recipe with the same id as a bundled one takes priority. Malformed files are skipped, not fatal — a typo in one recipe won't break stacktora recipes for everything else.
Company policy
Drop a company.stacktora.json next to your stacktora.json and stacktora audit checks the local recipe against it — a lightweight way to enforce an org's standards without any server:
{
"company": "Acme Inc.",
"policy": {
"allowedRuntimes": ["node", "python"],
"requiredTools": { "formatter": "prettier", "linter": "eslint" },
"allowedDatastores": ["postgres", "redis"],
"bannedDatastores": ["mongo"],
"allowedServices": ["kafka"],
"bannedServices": ["rabbitmq"],
"requireEnvSource": true,
"requiredOutputs": ["k8s", "precommit"],
"requireHealthGate": true
}
}Every policy field is optional — include only the ones you want enforced. allowedDatastores/allowedServices are allowlists (anything outside them fails); bannedDatastores/bannedServices are denylists (anything inside them fails) — use whichever fits how your team thinks about it, or both at once. requireEnvSource fails any custom environment variable that doesn't have a source note set (see the secret-source section above). requiredOutputs checks that specific optional output files are toggled on. No company.stacktora.json in the directory means nothing to check, not an error; stacktora audit reports that plainly and exits cleanly. Exit code is 1 if anything violates policy, 0 if compliant, same convention as check/plan/doctor.
Remote recipes
Bundled and custom recipes are always instant and fully offline — that never changes. Add --remote when you explicitly want to also reach the public registry at stacktora.com/registry:
stacktora recipes --remote # lists remote recipes as a third category, above bundled ones
stacktora install acme-recipe --remoteWithout --remote, neither command ever touches the network — this is an opt-in, not a background behavior. The registry itself is static JSON, no accounts or submissions system yet; see stacktora.com/registry/README.md for the exact format if you're publishing one.
stacktora doctor --json | jq '.checks[] | select(.ok == false)'A typical update flow:
stacktora plan # see exactly what's drifted, line by line
stacktora sync # apply it
git diff # review, then commitSafety
.envis never touched — your real local secrets are safe..env.exampleis regenerated; copy what you need.synconly writes files that actually changed, and prints each one. Everything is plain text under version control — review withgit diffbefore committing.- The recipe in
stacktora.jsoncontains no secrets — just your stack definition. It's safe to commit.
Editing the recipe
stacktora.json is yours to edit by hand (bump a version, add a service, change a port) and re-sync, or regenerate it visually at stacktora.com and commit the new file.
Secret source references
Each custom environment variable can optionally carry a source — a plain-text pointer to where the real value actually lives (a vault path, a 1Password item, wherever your team keeps it). It never holds the real secret itself, just where to find it:
{ "key": "STRIPE_SECRET_KEY", "value": "sk_test_xxx", "source": "1Password > Acme > Stripe" }Stacktora prints that as a comment directly above the variable in both .env.example and .env:
# from: 1Password > Acme > Stripe
STRIPE_SECRET_KEY=sk_test_xxxsource is fully optional — omit it and nothing changes from today's output. Existing stacktora.json files need no changes to keep working exactly as they do now.
Coding-standard config generation
If your formatter is Prettier, tools.codeStyle lets you declare real formatting preferences and get a matching .prettierrc.json generated for you:
"tools": { "packageManager": "npm", "formatter": "prettier", "codeStyle": { "semicolons": false, "singleQuote": true, "printWidth": 100 } }Unset fields fall back to Prettier's own defaults (semi: true, singleQuote: false, printWidth: 80, tabWidth: 2, trailingComma: "all"). codeStyle is fully optional — leave it out entirely and no .prettierrc.json is generated at all, exactly matching today's behavior. Nothing about an existing recipe needs to change.
Part of Stacktora — define your stack once, run it the same way everywhere.
