Skip to content

How-To · REST API (Node)

Backend · Estimated time: ~15 min · Karajan iterations: 2–3

This walkthrough takes you from an empty directory to a merged endpoint on a small Node + Express REST API. It includes the exact test loop Karajan uses to gate merges (supertest + Vitest), so you can re-run it on a real codebase by swapping the bootstrap step for cd <your-repo>.

You should already have done the common setup: npm install -g karajan-code, kj init inside the project, and a green kj doctor. If kj doctor is red, fix that first — kj run will refuse to start otherwise.

  1. Bootstrap the project.

    Terminal window
    mkdir hello-api && cd hello-api
    npm init -y
    npm install express
    npm install --save-dev vitest supertest
    git init -b main && git add -A && git commit -m "chore: scaffold"

    Edit package.json so the test runner is wired up:

    {
    "type": "module",
    "scripts": {
    "test": "vitest run",
    "start": "node src/server.js"
    }
    }

    Create a minimal src/app.js skeleton (no routes yet) so Karajan has something to extend:

    import express from "express";
    export function createApp() {
    const app = express();
    app.use(express.json());
    return app;
    }
  2. Initialize Karajan in the repo.

    Terminal window
    kj init
    kj doctor

    kj init creates .karajan/ and writes the orchestrator config; kj doctor confirms the agent CLIs, Docker, Ollama, and ports are all healthy.

  3. Describe the endpoint in natural language.

    No spec file. No JSON. Just the task as you’d describe it to a colleague:

    Terminal window
    kj run "Add a GET /greet?name=<name> endpoint to src/app.js that \
    returns JSON { greeting: 'Hello, <name>!' }. If 'name' is missing, \
    return 400 with { error: 'name is required' }. Add Vitest tests \
    using supertest covering both cases." \
    --methodology tdd \
    --coder claude \
    --reviewer codex \
    --reviewer-fallback claude \
    --max-iterations 5
  4. Watch the run on the HU Board.

    Open http://localhost:4000 in another tab while the pipeline runs. You’ll see, in real time:

    • Each role activating (planner → coder → tester → reviewer).
    • The exact prompt + response of every agent call.
    • The diff after each iteration.
    • The supertest HTTP traces.
    • The reviewer verdict.

    You can also tail the same trace in the terminal:

    Terminal window
    kj tail
  5. Inspect the result.

    Terminal window
    git status
    git diff --stat
    npm test

    Expected output of npm test:

    ✓ tests/greet.test.js (2)
    ✓ returns 200 + greeting JSON for a valid name (19ms)
    ✓ returns 400 + error when name is missing (6ms)
    Test Files 1 passed (1)
    Tests 2 passed (2)

    Sanity-check live:

    Terminal window
    npm start &
    curl -s "http://localhost:3000/greet?name=world"
    # {"greeting":"Hello, world!"}
  6. Merge.

    Karajan does not push or merge for you by default — that’s your call. When you’re happy with the diff:

    Terminal window
    git checkout -b feat/greet-endpoint
    git add -A && git commit -m "feat(api): add GET /greet endpoint"
    git push -u origin feat/greet-endpoint
    gh pr create --fill

    Or, if you want Karajan to also open the PR for you, add --auto-commit --auto-pr to the kj run invocation.

The same run launched via the MCP from any MCP-capable client (Cursor, Claude Desktop, Codex):

{
"tool": "kj_run",
"params": {
"task": "Add a GET /greet?name=<name> endpoint with 200 happy + 400 missing-name. Tests with supertest.",
"methodology": "tdd",
"coder": "claude",
"reviewer": "codex",
"reviewerFallback": "claude",
"maxIterations": 5
}
}