CLI

@solid-mvc/cli is the project toolkit — Angular CLI shaped: scaffold apps, generate views/controllers/services/ modules/islands, run the project's vite and vitest, add integrations, and bump framework deps.

Install

npm install -g @solid-mvc/cli
# or run without installing:
npx @solid-mvc/cli <command>

The binary is smvc (with solid-mvc as a longer alias). It is dependency-free Node — it must run before a project has node_modules at all.

New application

smvc new my-app                  # core app: module + router + two views + a test
smvc new my-app --islands      # + worker-island demo (contract, worker, route)
smvc new my-app --tailwind     # + Tailwind v4 wired into vite and styles
smvc new my-app --skip-install # write files only

The scaffold is the same shape this site documents: AppModule with RouterModule.forRoot, an AppShell view, a standalone HelloView, a stateful CounterView, jsdom test stubs, and the decorators-friendly tsconfig. Existing files are never overwritten unless --force; -d/--dry-run prints the plan without writing.

Generators

smvc g view user-card        # src/app/user-card/user-card.view.tsx (+ .test.tsx)
smvc g controller checkout   # checkout.controller.ts — @Controller view logic
smvc g service session       # session.service.ts — @Injectable model
smvc g module admin          # admin.module.ts — feature module
smvc g island ticker         # islands/ticker.contract.ts + workers/ticker.worker.tsx

smvc g view report --path src/app/admin   # override the target directory
smvc g view report --skip-tests           # no spec file

Generators print the next step — the route entry or declaration to add — rather than editing files in place. The island generator emits the contract-first shape (worker factory inside the contract, islandComponent on the shell); run smvc add islands first if the atoll packages are not installed.

Serve, build, test

Thin pass-throughs to the project's own toolchain — every flag after the command goes to vite/vitest:

smvc serve --port 3000      # vite dev server
smvc build                  # tsc --noEmit && vite build (--no-typecheck to skip)
smvc test                   # vitest run
smvc test --watch           # vitest watch mode

Integrations

smvc add tailwind   # deps + vite plugin + styles.css
smvc add islands    # @solid-mvc/atoll + atoll-island + @atolljs/core

Updates

smvc update                 # bump every @solid-mvc/* dep to latest, npm install
smvc update --to 0.2.0      # pin to a specific release
smvc update -d              # show the planned changes only
smvc update --include-atoll # also bump @atolljs/* deps

smvc version prints the CLI version plus the detected framework dep ranges of the project you're inside.

Generated tests mount views through InjectorContext.Provider — a bare render() has no injector context, so inject() throws by design. The generated vite config aliases solid-js to its client build so the whole graph resolves one runtime realm — without it, the node condition picks the server build where effects never run.