Web App Template Summary¶
What the web stack adds¶
The Harness Toolkit web stack creates a deployable TypeScript web app
foundation for projects that need a browser UI, API routes, and a path to
login-owned persistence.
Generate it with:
The generated app uses:
- Vite + React for the browser app
- TypeScript for app, worker, and tests
- Cloudflare Workers for API routes and hosting
- Cloudflare Static Assets for serving the Vite build
- D1 migrations for relational saved-run style data
- Vitest for tests
- ESLint and Prettier for code quality
- Wrangler for local Worker development and deploy dry-runs
Optional variants:
--web-ui tailwindadds Tailwind v4 through the Vite plugin--web-ui shadcnadds Tailwind plus shadcn-compatibleButton,cn(), andcomponents.jsonscaffolding--web-db drizzle-d1keeps Cloudflare D1 but uses Drizzle's D1 adapter and a generatedworker/db/schema.ts
Generated layout¶
my-dashboard/
├── index.html
├── package.json
├── wrangler.jsonc
├── src/
│ ├── app/App.tsx
│ ├── main.tsx
│ ├── sim/savedRun.ts
│ └── styles.css
├── worker/
│ ├── index.ts
│ ├── auth/README.md
│ ├── db/savedRuns.ts
│ └── routes/
│ ├── health.ts
│ └── runs.ts
├── migrations/
│ └── 0001_auth_and_saved_runs.sql
├── tests/
│ ├── app.test.ts
│ └── worker.test.ts
└── public/data/.gitkeep
Variant-only files:
components.json # --web-ui shadcn
src/components/ui/button.tsx # --web-ui shadcn
src/lib/utils.ts # --web-ui shadcn
worker/db/schema.ts # --web-db drizzle-d1
For single-project web init, the template replaces the scaffold repo's Python
tests/ tree before copying the web Vitest tests. That prevents generated web
repos from inheriting Harness Toolkit's own test suite.
Task contract¶
The generated .mise/tasks/* dispatch to web-native tooling:
mise run setup # npm install --package-lock=false
mise run fmt # prettier --write
mise run lint # eslint
mise run typecheck # tsc --noEmit
mise run test # vitest run
mise run build # vite build
mise run check # fmt-check + lint + typecheck + test
mise run verify # check + build + wrangler deploy --dry-run
mise run dev # build + wrangler dev --local --port 8787
CI smoke coverage includes --stack web, so the scaffold repo verifies that a
fresh generated web project can initialize successfully.
Cloudflare shape¶
The generated wrangler.jsonc includes:
assets.directory = "./dist"assets.binding = "ASSETS"- a D1 binding named
DB workers_dev = true
The Worker includes:
GET /api/healthGET /api/runs/minePOST /api/runs
Saved runs use a generic relational table:
idowner_idtitlelineup_jsonresult_jsoncreated_at
The default --web-db d1 generated Worker uses raw D1 prepared statements.
The optional --web-db drizzle-d1 variant keeps the same Cloudflare binding and
migration, but performs reads/writes through drizzle-orm/d1.
The saved-run routes now require a real authenticated owner outside localhost.
In deployed environments, requests return 401 until the app wires a validated
auth provider; the template does not trust caller-supplied identity headers by
default.
What is intentionally stubbed¶
The web stack does not pretend to know final production choices for every app. It leaves these as explicit app-level follow-ups:
- production D1 database id
- Cloudflare Access policy or app-native auth provider
- custom domain or Worker route
- R2 buckets for larger object storage
- Vercel deployment alternative
- Postgres provider if the app chooses conventional relational hosting outside Cloudflare
The default recommendation remains Cloudflare-native for simple apps that want one deploy surface: Worker compute, static hosting, D1 relational persistence, and a deliberately wired auth provider.
Known follow-ups for the template¶
Useful next improvements:
- add a generated "launch/deploy" how-to to every web app
- add an optional
--auth cloudflare-accessmode once the auth shape settles - add optional
--persistence none|d1once non-persistent marketing/tool apps are common - add a
--portoverride formise run dev - consider an explicit
npm audittask so dependency audit findings are visible but do not surprise the main quality gate