Web field Plate 59 Route §59
Plate 59

The full-stack app with an admin

Pages for the people who use it, and a generated CRUD surface for the person who has to fix a row at eleven at night.

The admin is derived from the same defineSchema the app already uses, so it cannot drift from the tables. Search fields, filters, bulk actions and read-only models are configuration, not a second application.

It mounts behind your auth. It is a full administrative surface over your database — treat an unprotected basePath as a public database.

What you are carrying

@atlas/server

Routes and static serving.

@atlas/db

Schemas the admin reads its shape from.

@atlas/auth

Who gets in, and who gets into `/admin`.

@atlas/admin

Generated list, detail, create, filters, bulk actions.

@atlas/ui

React blocks for the half people see.

Start it

atlas init -n myapp --template admin

What it looks like

src/admin.tsts
import { admin, model } from "@atlas/admin"
import { users, uploads } from "./schema"

const panel = admin({
  db,
  basePath: "/admin",
  auth: { secret: config.secret },   // not optional in production
  models: [
    model({ schema: users, searchFields: ["email", "name"], filterFields: ["createdAt"] }),
    model({ schema: uploads, searchFields: ["filename"], readOnly: true }),
  ],
})

serve({ port: 3000, routes: [...appRoutes, ...panel.mount([])] })

Read next

@wess/atlas/admin @wess/atlas/ui Quick start
Type to search guides and package references.