Skip to content
EvalBook

Local development

Ports, every environment variable, a local SSO, the database, peers, and the checks to run before handing work over.

EvalBook runs locally as three processes from one repository: the API, the worker and the web app. Development and tests use SQLite files; production uses one PostgreSQL database. Node 24 is required (nvm use 24.19.0).

You need a Bookbag SSO to sign in to, and it must be a local one, never production: see The local e2e SSO. Organizations, people and roles are managed there; EvalBook reads them live, and platform administration follows SSO's per-product role for EvalBook.

Quick start

source ~/.nvm/nvm.sh && nvm use 24.19.0
npm install && npm install --prefix nextjs-app
# write .env.local (gitignored) as the table below describes
npm run bootstrap                                  # tables for every context (fresh database)
npm run dev                                        # API on :8086
npm run worker                                     # jobs and deliveries (second terminal)
npm run dev --prefix nextjs-app                    # web on :3006 (third terminal)

Ports

Process Port Command
API 8086 (EVALBOOK_HTTP_PORT overrides) npm run dev
worker none npm run worker
web 3006 npm run dev --prefix nextjs-app
tests 0 (the OS picks) npm test, npm run test:e2e

On a machine shared with the sibling products, never bind their ports: 8083, 3003, 8090, 3200, 8081, 3100, 3000, 18080, 18090 and 8080. npm start in nextjs-app binds 3000 and is for the container only.

Environment

npm run dev, npm run worker and npm run seed read .env.local, which is gitignored. The development environment file holds the shape and the non-secret defaults; the variables below win over it. Never commit a value.

Variable Needed for Notes
SSO_ORIGIN everything that talks to SSO Set it. Unset, the server addresses the production SSO. Local e2e SSO: http://localhost:8290
SSO_ISSUER sign-in only when the issuer differs from SSO_ORIGIN
SSO_APP_TOKEN sign-in, organization reads, AI, files, billing, peer directory issued by SSO's app registry (the e2e SSO writes it to tokens.env)
SSO_UI_ORIGIN links to SSO pages the API builds set it when the SSO UI and API are on different ports (e2e: http://localhost:3290)
EVALBOOK_ENCRYPTION_KEY secrets at rest 32 bytes as 64 hex characters or base64. Without it, storing a secret throws and /ready fails the encryption check
EVALBOOK_APP_URL links EvalBook writes (peer links, emails) default http://localhost:3006
EVALBOOK_ALLOWED_ORIGINS CORS beyond http://localhost:3006 comma-separated
EVALBOOK_INLINE_WORKER=1 running jobs inside the API process for tests and quick local runs; normally run npm run worker
PEER_SECRET, PEER_CODEBOOK_URL, PEER_MADEBOOK_URL, EVALBOOK_PUBLIC_API_URL local peer overrides replace SSO's peer directory for local work; their names are logged at boot, never their values
EVALBOOK_PRIVATE_HOSTS letting outbound calls reach named local hosts e.g. localhost:8283 for a local CodeBook; private addresses are refused otherwise
EVALBOOK_DIAGNOSTICS_TOKEN /ready detail for a monitor optional, at least 32 characters
LOG_LEVEL logging debug, info (default), warn, error
JOB_POLL_MS, OUTBOX_SCHEDULE_MS, RETENTION_FIRST_MS, JOB_CONCURRENCY_<QUEUE> worker timing defaults suit production
EVALBOOK_DB_HOST, _PORT, _NAME, _USER, _PASSWORD, _SSL, _SSL_INSECURE PostgreSQL (container) turned into the connection override at container start

Generate the encryption key straight into the file without printing it:

printf 'EVALBOOK_ENCRYPTION_KEY=%s\n' "$(node -e "process.stdout.write(require('crypto').randomBytes(32).toString('hex'))")" >> .env.local

The web app reads nextjs-app/.env.local: NEXT_PUBLIC_SSO_ORIGIN is the SSO UI origin for sign-in, sign-out and account links (set it; e2e SSO: http://localhost:3290; unset means production), API_ORIGIN is where /api/* is proxied (default http://localhost:8086), and NEXT_DIST_DIR is the build output directory.

Database

  • Fresh database: npm run bootstrap creates every table from the current entities in every context; safe to re-run, it adds missing tables and columns only.
  • Migrations: npm run migrate applies pending ones in every context.
  • SQLite files live in db/ and are gitignored. To start over, stop the API and worker and move them aside.
  • Data: npm run seed -- --org <SSO org id> --admin <member email> --project "<name>" creates one real project through the same service the UI uses. There is no demo data.

Peers

CodeBook and MadeBook find EvalBook through SSO's peer directory. For a local pair, run their feat/evalbook worktrees against the e2e SSO (CodeBook on 3283/8283, MadeBook on 3281/8281). See Peer links.

Checks before handing work over

npm test                                  # unit tests, authorization coverage (0 unprotected), cookie isolation
npm run test:e2e                          # the real API over HTTP on port 0 against a fake SSO and fake peers
cd nextjs-app && npm run build:check; echo $?    # 0; builds into .next-check, safe while next dev runs
npx eslint .

The fake SSO and fake peers in test/support/ are declared test doubles, never used outside tests.