Skip to content

Unify webjs dev/start/db with npm-script behavior via a declarative tasks config #550

@vivek7405

Description

@vivek7405

Problem

webjs dev / webjs start and npm run dev / npm run start behave differently today, and only the npm-script forms work as expected. The orchestration (Tailwind's css:watch, predev: prisma generate, prestart: prisma migrate deploy) lives in package.json via concurrently + lifecycle hooks, so bare webjs dev/start (the framework primitives) skip all of it. An agent (or human) who runs the bare CLI gets an app with no compiled CSS and stale/absent generated code. This is the #452 gap, and it also blocks offering both webjs db and npm run db:* as equivalent.

Design / approach

Move the orchestration INTO webjs dev/start via a small declarative tasks config in the package.json "webjs" block, and make the npm scripts thin aliases so the two are identical by construction.

"webjs": {
  "dev":   { "parallel": ["tailwindcss -i ./public/input.css -o ./public/tailwind.css --watch"] },
  "start": { "before":   ["webjs db migrate"] }
}
"scripts": { "dev": "webjs dev", "start": "webjs start" }

webjs dev reads the config, runs the parallel watchers alongside the server (absorbing the concurrently role), and webjs start runs the before steps then the server. npm run dev becomes literally webjs dev, so both forms behave identically. The same applies to webjs db vs npm run db:*: behavior lives in webjs, so both work.

Scope guard: webjs takes on a small, bounded orchestrator role (running the configured commands), declarative and capped, NOT a bundler, so it does not cross the no-build line any more than today's Tailwind watch already does. The dev/prod split still holds: dev runs parallel watchers; prod (start) runs before steps (e.g. migrate) then serves, and must NOT run codegen in a read-only container.

Note: the Drizzle ORM default (separate issue) removes the prisma generate codegen footgun, so once that lands the only orchestration to absorb is Tailwind (dev) and migrate-apply (start), which is a small, well-defined set.

Implementation notes (for the implementing agent)

  • CLI entry: packages/cli/bin/webjs.js (the dev/start/db command handlers; today the dev preflight hint is ~L101-108 and case 'db' ~L147). The tasks-config reading + orchestration hooks in here.
  • Server boot: startServer in @webjsdev/server (runtime-neutral listener seam). The parallel watchers run as child processes alongside the listener; ensure clean teardown on SIGINT/SIGTERM (kill children, like concurrently --kill-others-on-fail).
  • Config surface: the package.json "webjs" block (already used for headers/CSP/redirects/trailing-slash/basePath, typed by WebjsConfig). Add dev/start task fields + JSON Schema + the WebjsConfig type.
  • Scaffold: packages/cli/lib/create.js generates the scripts + "webjs" block; update so generated scripts.dev/start are thin aliases and the tasks config carries Tailwind/migrate.
  • Landmines: dogfood: DX papercuts — redirect() defaults to 307; bare webjs dev skips predev #452 (the root cause); running configured shell commands is a capability to keep bounded/declarative (do not turn it into an arbitrary task runner); ensure child-process teardown so webjs dev does not leak a Tailwind watcher; on Bun the listener shell differs (Bun.serve), so verify orchestration + teardown on BOTH runtimes.
  • Invariants: stays buildless (no bundler); the webjs dev/start primitives must remain runnable with an empty/absent tasks config (a plain app with no Tailwind/DB still works).
  • Tests + docs: CLI tests that bare webjs dev runs the configured parallel tasks and tears them down; scaffold-integration assertion; a Bun cross-runtime check; docs agent-docs/configuration.md (the "webjs" block) + agent-docs/deployment.md (start before steps) + root AGENTS.md CLI section.

Acceptance criteria

  • webjs dev and npm run dev produce identical behavior (CSS compiled, watchers running); same for webjs start / npm run start.
  • Bare webjs dev run on a fresh scaffold serves a fully-working, styled app with no manual pre-steps.
  • webjs db <sub> and npm run db:* are equivalent.
  • Configured parallel watchers are torn down cleanly on exit (no leaked processes), verified on Node AND Bun.
  • A counterfactual proves the orchestration test fails when the tasks config is ignored.
  • Docs ("webjs" block, deployment) + AGENTS.md CLI section updated.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions