Skip to content

Repository files navigation

Switchboard

NOT STABLE

Switchboard is a Next.js, Prisma, and TypeScript project for generating database-backed admin resources and routes from a Prisma schema. The CLI is published as @lanebucher/switchboard.

Quick Start

From an existing Next.js App Router and Prisma project:

npm install -D @lanebucher/switchboard@beta
npx switchboard init
npx switchboard generate --pages
npx switchboard auth seed-admin
npm run dev

Beta warning: Switchboard is in early beta. Test it in a branch first and use --dry-run before writing generated files. Change any default admin credentials in the host project before deploying to production.

Before generation, configure Prisma normally. For SQLite:

DATABASE_URL="file:./dev.db"
SWITCHBOARD_SESSION_SECRET="replace-with-at-least-32-random-characters"

Create the database and generate the Prisma client:

npx prisma migrate dev --schema src/prisma/schema.prisma
npx prisma generate --schema src/prisma/schema.prisma

Open http://localhost:3000/admin and sign in with admin / password. Those credentials are only for local bootstrap. Change the password before production with switchboard auth seed-admin --admin-password <password>.

init supports projects using either src/app or root app and detects the standard Prisma schema locations. A matching @/* path alias is used when available; otherwise generated files use relative imports.

Example App

examples/basic-next-prisma is a standalone Next.js, Prisma, SQLite, and TypeScript app that uses the local CLI package the same way an outside project would.

Run its complete install, migration, generation, and production build check:

npm run example:smoke

Local Development

Requirements:

  • Node.js 20.9.0 or newer
  • npm

Set up the repository:

git clone https://github.com/black-candle-technologies/switchboard.git
cd switchboard
npm install

Create the local environment file:

cp .env.example .env

On PowerShell, use:

Copy-Item .env.example .env

The SQLite connection must be:

DATABASE_URL="file:./dev.db"

Prisma resolves that path relative to src/prisma/schema.prisma, so the local database is created at src/prisma/dev.db.

Initialize and seed the database, then start the app:

npm run db:migrate
npm run db:seed
npm run dev

Open http://localhost:3000/admin. The generated resource routes are under /admin/<resource>, for example /admin/users.

CLI Development

Link the CLI from this repository:

cd packages/cli
npm install
npm link

Then run it from the root of a compatible Next.js project:

switchboard init
switchboard generate --pages

To test the published package without linking it globally:

npx @lanebucher/switchboard generate --pages

Initialize A Project

switchboard init [options]
Option Description
--schema <path> Use a custom Prisma schema path.
--app-dir <path> Use a custom App Router directory.
--force Overwrite existing Switchboard support files whose contents differ.
--dry-run Print detected paths and planned actions without writing files.

By default, init preserves existing files. It creates the Prisma helper, Switchboard types/registry/overrides, form and table components, and the admin layout/index. It also creates app/admin/switchboard.css, a small framework-free stylesheet that can be edited or replaced. It supports both src-based and root-based projects. Authentication is generated by default.

The Prisma schema must contain a User model with one scalar @id, a unique String username or email, a String passwordHash or password, and an enum role whose enum includes ADMIN. Switchboard reports missing fields and does not modify the schema.

Set SWITCHBOARD_SESSION_SECRET to a random value of at least 32 characters. If a project already has middleware.ts, init refuses to claim /admin is protected unless the generated guard is integrated or --force explicitly replaces that file.

Bootstrap Admin

npx switchboard auth seed-admin
npx switchboard auth seed-admin \
  --admin-username admin \
  --admin-password "use-a-strong-password"

The command creates or resets an administrator using a salted Node scrypt hash. The default admin / password credentials are insecure and intended only for local development. --dry-run checks the schema and database record without writing. Password fields generated in User forms are hashed and never shown in resource lists.

Generate Resources

The generator prefers src/prisma/schema.prisma and src/app, then falls back to prisma/schema.prisma and root app. Switchboard output defaults to src/switchboard or root switchboard to match the detected layout. It reads @/* mappings from tsconfig.json or jsconfig.json; projects without a usable alias receive relative imports automatically. Use --schema and --app-dir to override detection.

switchboard generate [options]
Option Description
-m, --model <name> Generate only one Prisma model.
--schema <path> Schema path relative to the project root.
--out <path> Switchboard output root inside the detected source root.
--app-dir <path> Use a custom App Router directory.
--pages Also generate App Router admin pages.
--force Overwrite existing resource configs and admin page files.
--dry-run Print detected paths and planned actions without writing files.

Example with custom paths:

npx switchboard generate \
  --schema prisma/schema.prisma \
  --out src/admin-kit \
  --pages

Use --dry-run before generation to inspect every Would create, Would update, Would skip, or Would overwrite action. Dry-run creates no files or directories. Use --force only when existing generated configs or admin pages should be replaced.

--out changes the resource and registry location. Admin pages remain under the detected App Router directory’s admin folder.

Generated Output

init creates:

src/lib/prisma.ts
src/switchboard/types.ts
src/switchboard/registry.ts
src/switchboard/overrides.ts
src/switchboard/auth.ts
src/switchboard/auth-actions.ts
src/components/form/SmartForm.tsx
src/components/form/DeleteButton.tsx
src/components/table/SimpleTable.tsx
src/middleware.ts
src/app/admin/switchboard.css
src/app/admin/layout.tsx
src/app/admin/page.tsx
src/app/admin/login/page.tsx

Root app projects receive the same structure without the src/ prefix.

generate writes:

src/switchboard/generated/<Model>Resource.ts
src/switchboard/registry.ts

With --pages, it also writes:

src/app/admin/page.tsx
src/app/admin/layout.tsx
src/app/admin/<models>/page.tsx
src/app/admin/<models>/new/page.tsx
src/app/admin/<models>/[id]/edit/page.tsx

Generated resource configs and admin pages belong to the project and can be edited. Re-running generation reports matching files as unchanged and skips differing files by default. --force overwrites those files. init follows the same protection rule for support files.

The generated registry is maintained automatically when Switchboard recognizes its marker or the initial empty registry created by init. A custom or ambiguous registry is skipped unless --force is used.

Use --model to limit generation to one Prisma model:

npx @lanebucher/switchboard generate --model User --pages

Generated Runtime Support

Generated forms currently map Prisma fields as follows:

Prisma field Generated control
String Text input, with email/password/long-text heuristics
Int, Float, Decimal, BigInt Number input
Boolean Checkbox; optional booleans use a Yes/No/Not set select
Enum Select using the schema enum values
DateTime datetime-local input
Json Multiline JSON textarea
Optional scalar Blank values become null
Scalar with a default Blank values allow Prisma to apply the default

List pages format dates, booleans, JSON, and null values, validate search/sort query parameters against generated field allowlists, clamp pagination to valid pages, and show distinct empty states for an empty resource and an empty search.

For a relation such as author User @relation(fields: [authorId], references: [id]), Switchboard renders authorId as a select. Options use the referenced key as the value and prefer name, title, label, email, or username as the display field. List pages include that display field instead of showing only the raw foreign key.

Generated create, update, and delete actions report common Prisma unique, foreign-key, and missing-record errors in the page. Failed form submissions remain on the form so browser-entered values are retained.

Current runtime limitations:

  • Relations support selecting an existing related record only.
  • Nested create/update, many-to-many editors, scalar lists, and compound IDs are not generated.
  • Relation option lists are loaded in full; autocomplete and remote lookup are not generated yet.
  • Bytes fields do not receive a specialized upload control.
  • Generated validation is browser validation plus Prisma/server errors; domain validation remains application code.

Commands

Command Description
npm run dev Start the local Next.js app.
npm run lint Run ESLint.
npm run build Create a production build.
npm run db:generate Generate the Prisma client.
npm run db:migrate Apply local Prisma migrations.
npm run db:seed Seed the local SQLite database.

License

MIT

About

Switchboard is a modular, open-source admin panel and API scaffolding generator designed for applications built with Next.js, Prisma, & TypeScript.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages