Developer Docs

Local Development

The real day-to-day dev loop: running the backend and UI, scaffolding CQRS code, migrations, and managing local data with the ds CLI.

Local Development

Day-to-day DevStride development runs through the ds CLI (./ds from the repo root). This page covers the loop you'll use constantly once your stage is bootstrapped: starting the backend and UI, scaffolding new CQRS commands/queries, running migrations, and managing local data.

Running the App

Backend

ds run backend

This runs pnpm install, cleans up any orphaned CloudFormation stacks left over from a previous sst.config.ts change, and then starts pnpm exec sst dev — SST's live-lambda dev mode for the Hono backend. Leave this running in its own terminal; Ctrl+C stops it cleanly.

Frontend

ds run ui

Spawns pnpm run dev inside frontend/, injecting VITE_* env vars (API/auth/media URLs, Pusher keys, Stripe public key, etc.) derived from your bound stage. The UI serves on http://localhost:8080.

Run both ds run backend and ds run ui together in separate terminals for the normal dev loop.

Scaffolding CQRS Code

DevStride's backend follows a strict CQRS layout per module (see API Development for the full Hono route → CommandBus/QueryBus call flow). Rather than hand-rolling the boilerplate, use ds g to scaffold a new command or query:

ds g command <Name> -m <module>
# alias: ds g c <Name> -m <module>

ds g query <Name> -m <module>
# alias: ds g q <Name> -m <module>

-m / --module is required — it's the target module directory (e.g. item, board, service-desk). Add -f / --force to overwrite an existing scaffold with the same name.

Running ds g command SendInvite -m user creates backend/src/modules/user/commands/send-invite/ with:

  • send-invite.command.ts — the Command class (props)
  • send-invite.service.ts — the CommandHandlerBase implementation (your business logic goes here)
  • send-invite.init.ts — registers the handler on the CommandBus
  • send-invite.lambda.handler.ts — an HTTP entry point that constructs the command and executes it via CommandBus

ds g query scaffolds the equivalent layout under queries/<kebab-name>/ for QueryBus-backed reads.

Migrations

ds migrations run

Runs the Drizzle SQL migrations against your bound stage's database, bringing it to the latest schema. This is what you run after pulling in someone else's schema changes, or after authoring your own with pnpm -C backend generate-sql.

Managing Local Data

The ds data commands operate on SQL tables in your bound stage's database. import, wipe, and copy are all blocked outright on prod. export is not blocked — there's no prod guard on it in source, so it will run (read-only) against a prod-configured stage if you point one at it.

Import

ds data import <path> [-t/--tables <csv>]

Bulk-restores SQL tables from a previously exported directory (see Export below). Use -t to restore only specific tables (comma-separated table names); omit it to restore everything found at <path>.

Export

ds data export [path] [-t/--tables <csv>]

Dumps SQL tables to disk. If you omit path, it defaults to .ds/data/<stage>/sql. Use -t to export only specific tables.

Wipe

ds data wipe [-t/--tables <csv>]

Deletes rows from the selected tables (or all tables, if -t is omitted). Blocked on prod.

Copy (org-scoped)

ds data copy [-o/--organization <id>] [-s/--source <envVarName|connString>]

Copies a single organization's data from a source database into your bound stage's database. -s accepts either the name of an env var holding a connection string (e.g. GOLDEN_DB_CONNECTION_STRING) or a full connection string directly; if omitted in an interactive terminal you'll be prompted to pick from the *_CONNECTION_STRING vars in .env, and non-interactively it falls back to SOURCE_DB_CONNECTION_STRING.

Full Reset

ds script reset-db

After Changing a Backend Route

If you add, remove, or change a Hono route's path, request/response shape, or query parameters, the frontend's typed API client will go stale. Regenerate it before relying on the frontend to see your change — see API Development for the ds script generate-api-client command and what it does.

Next Steps