backstage-ai
v0.1.0
Published
Conversational CLI: local Ollama interviews you, fills a JSON spec, scaffolds Express + TypeScript + Docker.
Maintainers
Readme
backstage-ai
backstage-ai is a conversational CLI that uses a local Ollama model to interview you, scaffold a backend project from a structured spec, and run it locally in Docker.
You talk to the agent in your terminal — it asks what you want to build (entities, endpoints, auth, env vars), records your answers in a .backstage/spec.json file, and a deterministic scaffolder turns that spec into a real Node.js + Express + TypeScript project with a Dockerfile and docker-compose.yml.
- Package: backstage-ai on npm
Status: early MVP. Local-only. Auth website, payments, and cloud deploy targets (Supabase, Firebase, etc.) are on the roadmap.
Tutorial: install everything and run the CLI
Use this path when you are installing from npm (no source checkout). You need Ollama, a Gemma 4 model (or another tool-capable model), Docker Desktop, and Node.js 18+.
| Step | What to do |
|------|------------|
| 1 | Install Ollama from ollama.com/download, then start it (menu bar app on macOS, or run the daemon). |
| 2 | Pull Gemma 4 (see Ollama library: gemma4 for sizes and tags). |
| 3 | Install Docker Desktop from docker.com/products/docker-desktop and wait until Docker is running. |
| 4 | Install Node.js 18+ from nodejs.org if you do not already have it. |
| 5 | Install the CLI globally: npm install -g backstage-ai. |
Commands (copy in order):
# After Ollama is installed and running:
ollama pull gemma4
# Optional: smaller / edge variant (see library page for other tags)
# ollama pull gemma4:e2b
# After Docker Desktop is running:
docker compose version
# Install the CLI (global install so `backstage-ai` is on your PATH):
npm install -g backstage-ai
# Smoke checks
ollama list
backstage-ai --helpCreate and run your first API project:
mkdir my-api && cd my-api
backstage-ai init
# Complete the wizard; when asked for a model, choose gemma4 (or the tag you pulled, e.g. gemma4:e2b).
# After the agent finalizes and files exist:
backstage-ai run
# or, to rebuild the image every time:
backstage-ai deployUseful follow-ups:
backstage-ai update # change spec with AI or guided menus
backstage-ai models # list Ollama models, set default / host
backstage-ai spec # open spec viewer in the browserIf Ollama runs on another host, set OLLAMA_HOST (see Prerequisites).
Why spec-driven?
Small local LLMs are unreliable at writing whole files. Instead, the agent only ever calls tools that mutate a structured spec (add_model, add_endpoint, set_auth, finalize, …). A separate, deterministic scaffolder renders the spec to files. This is much more reliable than asking a 7B model to emit code blob by blob.
Prerequisites
- Node.js 18+
- Ollama running locally — install from https://ollama.com/download, then pull at least one model with solid tool calling (see tutorial above for Gemma 4):
ollama serve # optional; often the desktop app already runs the daemon ollama pull gemma4 # or gemma4:e2b / other tags — see https://ollama.com/library/gemma4 ollama pull llama3.1 # alternative; supports tool calling ollama pull qwen2.5 # alternative; strong at tool calls - Docker — Docker Desktop (or Engine) with Compose v2, required for
backstage-ai run/backstage-ai deploy.
Recommended models
backstage-ai uses Ollama's native tool-calling. Models known to work well:
| Model | Notes |
|--------------|--------|
| gemma4 | Gemma 4: native function-calling, strong coding/agentic use cases; several sizes (gemma4, gemma4:e2b, …). |
| llama3.1 | Solid tool calls at 8B. |
| qwen2.5 | Strong tool calls, good for code reasoning. |
| mistral | Often falls back to JSON-in-text parsing. |
If your model lacks native tool support, the CLI falls back to extracting JSON tool-call objects from the model's text. Prefer Gemma 4, llama3.1, or qwen2.5 for reliability.
Install
npm install -g backstage-aiDeveloping the CLI from source requires access to the project repository; use the npm install above if you only want to run backstage-ai.
Quickstart
mkdir my-api && cd my-api
backstage-ai initinit uses the current directory by default. You can still pass a path: backstage-ai init ./other-folder.
The CLI will:
- Check Ollama is reachable at
http://localhost:11434(override withOLLAMA_HOST). - Run the setup wizard: stack, database (none or Postgres), default model storage (
modelPersistenceDefault: auto follows database; or always memory / always Postgres), auth, port — then pick your local LLM for the design chat. - Start the conversation. The agent asks short questions about purpose, models, endpoints, auth, env vars. You answer in plain English.
- When the agent calls
finalize, the spec is saved to.backstage/spec.jsonand the project files are written.
You can change defaults anytime in backstage-ai update (guided) → Project defaults, including bulk-sync so every existing model matches the policy (no need to edit 100 models one by one).
Then run it:
backstage-ai run # docker compose up (uses cached image unless you pass --build)
backstage-ai deploy # docker compose up --build every time (local MVP deploy)
backstage-ai run --build # force rebuild when using run
backstage-ai run -d # detachedThe API is exposed on the port the agent picked (default 3000). When you run backstage-ai run or deploy, the CLI prints your spec’s endpoints and a curl example for /health—before Docker starts.
If you run backstage-ai init inside an existing project, the CLI detects it and lets you continue refining with more LLM questions or overwrite and start from scratch.
Commands
| Command | What it does |
|----------------------------------|-----------------------------------------------------------------|
| backstage-ai init [dir] | Chat with LLM to design the spec; every few tool rounds you get a checkpoint (finalize, view spec, or continue). |
| backstage-ai create [dir] | Same as init (alias flow). |
| backstage-ai update | Menu: AI chat or guided editor (models, endpoints, project defaults for database + default model storage + bulk sync). |
| backstage-ai run | Run generated API locally (docker compose up). |
| backstage-ai deploy | Local MVP deploy: docker compose up --build so changes always apply. |
| backstage-ai spec | Open the spec in your browser (writes .backstage/spec-view.html). Same as spec view. |
| backstage-ai spec view | Same as backstage-ai spec (explicit subcommand). |
| backstage-ai add model | No LLM — interactively add a model to the spec and re-scaffold. |
| backstage-ai add endpoint | No LLM — interactively add a route to the spec and re-scaffold. |
| backstage-ai models | List installed Ollama models, set a default, set Ollama host. |
Useful flags:
backstage-ai create --model qwen2.5 --name my-apibackstage-ai run --buildbackstage-ai specorbackstage-ai spec --cwd /path/to/projectbackstage-ai models --set-host http://my-server:11434backstage-ai models --set-default llama3.1
User config is stored in ~/.backstage-ai/config.json.
spec / spec view
- Use
backstage-ai specfrom your project root to open a readable copy of.backstage/spec.jsonin the browser (Chrome is preferred on macOS when installed). backstage-ai spec viewis the same action; theviewsubcommand exists for clarity and for users who expect a two-word command.- If you only run
backstage-ai spec, it does open the viewer — it is not a no-op. Options pass through toview(e.g.--cwd).
add model and add endpoint (no LLM)
These commands do not call Ollama. They read .backstage/spec.json, prompt you in the terminal (Inquirer), validate with the same Zod schemas as the AI tools, then write the spec and run the deterministic scaffolder (writeProject) so src/, routes, stores, Docker files, etc. stay in sync.
backstage-ai add model— Asks for PascalCase model name, optional description, memory vs Postgres persistence (Postgres setsdatabase: postgreson the project when applicable), then one or more fields (name, type, required, unique) in a loop. Rejects duplicate model names. Re-renders the whole project from the updated spec.backstage-ai add endpoint— Asks for HTTP method, path (must start with/), optional description, optional linked model (or none), handler (list/get/create/update/delete/custom), and requires auth. Rejects duplicate method+path. Re-renders the project.
Use these when you know exactly what to add and want a fast, non-conversational path. For open-ended design, use init or update.
What the scaffolder produces
A typical generated project layout:
my-api/
├── .backstage/spec.json # source of truth, read by `update`
├── .backstage/design-context.json # rolling chat summary + recent lines for `update` / next `init`
├── .backstage/spec-view.html # optional; generated when you “view spec”
├── Dockerfile
├── docker-compose.yml # api service (+ db service if Postgres)
├── package.json
├── tsconfig.json
├── .env # created on first scaffold (secrets; gitignored)
├── .env.example # template without real secrets
├── README.md
├── db/init.sql # only when Postgres is selected
└── src/
├── index.ts # Express app, mounts all route groups
├── db.ts # only when Postgres is selected
├── middleware/auth.ts # only when auth is enabled
├── models/<entity>.ts # one per spec model
├── store/<entity>.ts # in-memory or Postgres-backed
└── routes/<resource>.ts # one per resource groupEndpoints with handler: list|get|create|update|delete get real CRUD code; handler: custom produces a typed stub for you to fill in.
Roadmap
- Phase 2 — extra runtimes (Fastify, FastAPI), test scaffolding, richer
updatediffs. - Phase 3 — companion web dashboard with auth (Next.js).
- Phase 4 — paid hosted endpoints (Stripe + provisioning).
- Phase 5 — pluggable deploy adapters: Supabase, Firebase, Railway, Fly.io.
Troubleshooting
runsays there is no docker-compose.yml — You are not in the scaffolded project root, or files were never generated. Runbackstage-ai init/backstage-ai updatefrom that directory, or pass--cwd /path/to/project.- Docker “not on PATH” (macOS) — Open Docker Desktop, wait until it is running, then quit and reopen your terminal (or Cursor). Run
docker versionto confirm. The CLI also looks under/usr/local/bin,/opt/homebrew/bin, and Docker.app’s bundled CLI. npm startwith no subcommand — If you run the CLI entrypoint alone, you only see help. From npm, usebackstage-ai initin your project directory.- "Could not reach Ollama" — make sure Ollama is running, or set
OLLAMA_HOST. - Agent never calls
finalize— often a model that ignores tools. Try Gemma 4,llama3.1, orqwen2.5. You can also save the partial spec and continue withbackstage-ai update. - Docker not found — install Docker Desktop and ensure
docker compose versionworks. - Re-render after manual edits — run
backstage-ai update(or anyaddsubcommand). Your edits insidesrc/will be overwritten by re-rendering, so prefer the spec for structural changes.
Set BACKSTAGE_DEBUG=1 to print verbose logs.
License
Released under the MIT License.
