Tokyo Tester is a local-first end-to-end testing tool for service graphs and the infra they depend on.
You build workflows in the UI, run them through the Go runner, and keep workflow definitions, executions, logs, and test results synced back into the app.
If you want a higher-level walkthrough of how the pieces fit together, see How the system works.
If you want to get a feel for the product quickly, import test-workflow.json into the UI.
Before importing it, build the sample API image the workflow expects:
docker build -t bun-user-api:latest ./test-apiIn the workflow list, use Import Workflow, then select the file. It gives you a ready-made example with:
- a service graph
- a PostgreSQL dependency
- HTTP and database tests
- scenarios that show how runs are organized
- Build workflow graphs in the UI
- Provision services and dependencies through the runner
- Execute tests against the running stack
- Track workflow runs, logs, and results
- Persist workflow definitions locally first, then sync them to the backend
- Recover execution state from the backend when realtime delivery misses a beat
ui-v2is the Next.js app for editing workflows, scenarios, and executionsrunner-v2is the Go service that provisions containers, runs tests, and cleans updocker-compose.ymlwires the UI, runner, Postgres, and Inngest together for local development- the frontend sync layer persists queued edits locally, flushes them to
POST /api/v1/sync/batch, and hydrates fromGET /api/v1/sync/pull/{clientId} - Inngest coordinates execution, publishes realtime updates, and also persists workflow run status and logs so production runs can be recovered after reconnects or tab closes
make prodbuilds the standalone UI image and runs the production-like stack- the UI still uses Bun for app scripts, but database migration runs through
node ./src/db/migrate.mjsbecausebetter-sqlite3is a Node-only runtime dependency - workflow definitions are synced from the browser, while execution-owned records like workflow runs, scenario runs, and test results are treated as backend-owned during execution
- if you have an old UI image cached, rebuild the service before retesting production behavior:
docker compose build --no-cache uiThe easiest way to run everything locally is with Docker:
make devThat starts the dev stack with the UI, runner, and supporting services.
Useful commands:
make prod
make downIf you want to run pieces manually, the main environment values live in .env.example.
Common ports:
- UI:
http://localhost:3000 - Runner API:
http://localhost:8080 - Inngest dev server:
http://localhost:8288
- Next.js
- React
- Zustand
- Inngest
- Go
- Chi
- Docker
- testcontainers-go
- The project is still local/self-hosted by default.
- You do not need a deployed demo to explore the code or understand the workflow.
