Build apps
Local development
Run Hane's public API, console, and reference app on your machine, and build and test your app against sample data.
This page explains how to run Hane on a single machine and use it for app development. The local environment needs neither a Cloudflare account nor an LLM key. Outgoing email and calls go to emulators, so nothing leaves your machine.
Requirements
Section titled “Requirements”| Tool | Used for |
|---|---|
| Node.js 22.13 or later and pnpm 10 | Development servers and tests |
| Docker | Malware scanning of documents (ClamAV) and the CLI sandbox. The environment starts without it |
| Codex CLI or Claude Code | Only to run agents with driver: codex or driver: claude locally. Log in to the CLI beforehand |
Start Hane
Section titled “Start Hane”-
Install dependencies and start the development servers
ターミナルウィンドウ pnpm installpnpm devpnpm devstarts the development IdP, emulators for external providers, the public API gateway and core API, the console, and the reference app together. -
Load sample data
In another terminal, run the seed. It uses the public API and hanectl to create the development organization
acme, users, the projectfleet, the reference app’s service account and API key, definitions, and data.ターミナルウィンドウ pnpm dev:seedThe reference app’s API key is written to
examples/fleet/.dev.vars. Do not commit this file. -
Open the screens
Open the console (http://localhost:5173) or the reference app (http://localhost:5174) and pick a user on the development IdP’s screen. There are no passwords.
Ports and users
Section titled “Ports and users”| URL | What it is | User to log in as |
|---|---|---|
| http://localhost:8787 | Public API gateway | API key or access token |
| http://localhost:8788 | Development IdP (OIDC with PKCE) | — |
| http://localhost:5173 | Console | owner@example.test |
| http://localhost:5174 | Reference app (vehicle lease management) | fleet@example.test |
| http://localhost:8789 | Emulators. Shows the email and other messages Hane sent | — |
| http://localhost:5175 | UI library catalog (start with pnpm dev:ui) |
— |
All users are fictional. To check approvals, also log in as approver@example.test; to check read-only access, log in as viewer@example.test.
Use hanectl locally
Section titled “Use hanectl locally”The seed writes a hanectl context to .hane/hanectl.json. You can also log in again as a user of the local development IdP.
HANECTL_CONFIG=.hane/hanectl.json cli/hanectl/bin/hanectl.mjs rollout statuscli/hanectl/bin/hanectl.mjs login --dev-user owner@example.test --org acme --project fleet --env dev--dev-user gets an id_token only from the local development IdP. Access tokens expire after 15 minutes, but hanectl renews them automatically for contexts logged in with --dev-user.
Connect your app to local Hane
Section titled “Connect your app to local Hane”Your app’s BFF calls the local gateway (http://localhost:8787), just like the reference app. For user login, use the authorization code flow with PKCE against the development IdP (http://localhost:8788), then exchange the resulting id_token together with your app’s API key. See App structure and Authentication for how to write the BFF.
After changing definitions, run hanectl apply and then hanectl release create -f <bundle.yaml> --activate to rebuild the active release.
Choose an agent driver
Section titled “Choose an agent driver”With the default local profile of pnpm dev, agents with driver: llm run against fixed emulator responses, and CLI drivers do not run. To run agents with a CLI on your machine, stop the development servers and choose a profile.
pnpm dev:stopHANE_DEV_PROFILE=local-claude pnpm dev # Claude Code. Use local-codex for Codex CLIStop and reset
Section titled “Stop and reset”| Command | What it does |
|---|---|
pnpm dev:stop |
Stops what pnpm dev and pnpm dev:scanner started |
pnpm dev:reset |
Deletes local state (.hane/). Always run it after pnpm dev:stop |
pnpm dev:scanner |
In another terminal, starts the ClamAV Docker container used to scan documents |
pnpm dev:smoke |
Checks that the lease expiry flow runs end to end through the public API |
When you rename scopes or definitions, rebuild with pnpm dev:reset → pnpm dev → pnpm dev:seed. Service accounts created by an earlier seed keep their old scopes.
The sample data treats 2026-10-30 as today. As days pass, the contracts picked up by the daily detection and the days left until deadlines change.