Local Development with tawa dev

The Short Version

tawa dev reads your catalog-info.yaml, generates all platform environment variables, and either connects to real databases via SSH tunnels (online mode) or spins up a local mock server (offline mode). Your service runs locally with the exact same process.env it gets in production.

# Online mode (real databases, SSH tunnels)
tawa dev

# Offline mode (mock everything locally)
tawa dev --offline

# Start your dev server automatically
tawa dev --run

How It Works

  1. Catalog Analysis — Parses catalog-info.yaml for databases, dependencies, auth, routes, schedules, queues
  2. Environment Generation — Builds .env.local with all platform env vars (database URIs, service URLs, OAuth credentials, etc.)
  3. Connection Setup — Either creates SSH tunnels to real databases (online) or starts a mock server (offline)
  4. Dev Server (optional) — With --run, spawns your framework's dev command (next dev, tsx watch, etc.)

Online Mode (Default)

Connects to real platform databases via SSH tunnels through the jefferson server:

  • MongoDB, Redis, Neo4j tunnels auto-created based on spec.databases
  • Real connection strings written to .env.local
  • Tunnels stay alive with automatic reconnection
tawa dev
# Creates SSH tunnels, writes .env.local, waits for Ctrl+C

Offline Mode

Runs a local Express mock server on port 4500 that simulates all platform services:

Mock ServiceWhat It Does
Bio-IDReturns valid-looking JWTs, JWKS endpoint, user info
SeptorAccepts audit events, stores in memory
RelayLogs emails/SMS to console instead of sending
iec-queueAccepts job enqueues, logs them
iec-walletReturns mock balances
StorageFile upload/download with local filesystem

All mock data is stored in a local JSON file — no external dependencies needed.

tawa dev --offline
# Starts mock server on :4500, writes .env.local pointing to mocks

The --run Flag

Starts your dev server alongside mocks/tunnels. Detects the right command automatically:

  1. Checks package.json scripts.dev (most reliable)
  2. Falls back to framework defaults from catalog-info.yaml:
    • nextjsnpx next dev
    • express / hono / fastifynpx tsx watch src/index.ts
tawa dev --run           # online + dev server
tawa dev --offline --run # offline + dev server

The dev server inherits the generated .env.local and runs in the foreground. Ctrl+C cleanly shuts down everything (dev server, tunnels, mock server).

Generated Environment Variables

Core Platform

VariableValue
BIO_ID_URLhttps://bio.tawa.pro (online) or http://localhost:4500 (offline)
JANUS_URLInternal Janus URL or mock
KOKO_URLInternal Koko URL or mock
SERVICE_NAMEFrom metadata.name
SERVICE_NAMESPACE{name}-sandbox

Databases (from spec.databases)

DeclarationVariableOnlineOffline
type: mongodbMONGODB_URImongodb://localhost:{tunnel-port}/{name}-devmongodb://localhost:27017/{name}-dev
type: redisREDIS_URLredis://localhost:{tunnel-port}/0redis://localhost:6379/0
type: neo4jNEO4J_URIbolt://localhost:{tunnel-port}bolt://localhost:7687

Auth (from spec.auth)

VariableValue
BIO_CLIENT_ID{name}-dev
BIO_CLIENT_SECRETdev-secret-{name}

Internal Dependencies

Each entry in spec.internalDependencies generates {SERVICE}_URL:

  • Online: Janus proxy URL
  • Offline: http://localhost:4500/mock/{service}

All Flags

FlagDescription
--offlineUse local mock server instead of real connections
--runStart the dev server after setup
--port <n>Mock server port (default: 4500)
--env <name>Environment name for variable generation

Compiled Binary

The tawa CLI compiles to a standalone binary via bun build --compile:

# Build the binary (~61MB, arm64)
bun build src/index.ts --compile --outfile tawa-bin

# Run it — includes all commands including tawa dev
./tawa-bin dev --offline --run

The compiled binary includes all mock server code, tunnel manager, and env generator. No Node.js or npm required on the target machine.

Troubleshooting

ProblemFix
SSH tunnel failsCheck ssh jefferson works manually, verify SSH key
Mock server port takenUse --port 4501 or check lsof -i :4500
.env.local not picked upRestart your dev server — env files are read at startup
OAuth callback fails locallyAdd http://localhost:{port}/api/auth/callback to your Bio-ID client via tawa oauth add-uri
Missing env varCheck catalog-info.yaml — variable names derive from service declarations

Last updated: July 15, 2026