admin-kit

v0.2.0 · Next 15 & 16 · React 19

A Next.js admin toolkit you configure rather than fork.

Declare your endpoints, your permissions and your modules once; get a launcher panel, a sidebar panel, generated CRUD screens, and documentation of your own installation.

axiomkit — zsh — 80×24
# install, scaffold, and document your own config
pnpm add @cortejojicoy/admin-kit
npx admin-kit init
npx admin-kit docs

Three accounts, one password — demo. The same build, resolved three ways.

What you get

Six decisions the kit has already made, and the reasoning is in the docs rather than in a fork of it.

Every endpoint is yours

Login was pluggable in 0.1.x; now list, read, create, update, delete and any named action are too — declared per resource, with the wire format mapped in both directions.

Three-axis access control

Catalog (does the module exist?), entitlement (may this tenant run it?), permission (may this user open it?) — separately configured, with none / view / full levels rather than a boolean.

Two panels, split by work

A launcher for daily work that everyone lands on, and a sidebar panel for administration. Split by kind of work, not kind of account.

Serializable config

Plain data, so navigation resolves on the server with the user’s permissions already in hand — and a CLI can read the same config in plain Node.

Styled on install

One stylesheet driven by CSS custom properties. No Tailwind, no preset, no content globs — and every component takes a className.

Docs of your install

admin-kit docs writes markdown describing your endpoints, your roles and your screens. --check in CI stops it from drifting.

Configure it once, in plain data

AdminConfig is serializable on purpose. Icons are string keys resolved through a registry, visibility is declarative, and functions live only in the three places serializeConfig() strips at the boundary.

That constraint is what makes the rest work: navigation resolves on the server with the user's permissions already in hand, so the first paint shows the right menu — no client fetch, no flash of items they cannot see. And the CLI can read the same file in plain Node to write your docs.

Read the configuration reference

export const adminConfig = defineAdminConfig({
  app: { name: 'Axiomkit', logoIconKey: 'grid' },

  auth: {
    provider: 'jwt',
    jwt: {
      endpoints: { login: '/api/auth/login', me: '/api/auth/me' },
      tokenStorage: 'server-cookie',   // the browser never holds it
    },
  },

  access: {
    roles: { admin: ['*'], manager: ['users:*'] },
    deny:  { manager: ['users:delete'] },
  },

  resources: [{
    name: 'users',
    endpoints: {
      list:   '/api/users',
      remove: { method: 'DELETE', path: '/api/users/:id' },
    },
    permissions: { list: 'users:list', remove: 'users:delete' },
  }],
})

Three axes, and only one real gate

Hiding a control is not authorization, and neither is middleware. The axes decide what a user sees; the server guards decide what a request gets.

AxisQuestionIf the source cannot be read
CatalogDoes the module exist and is it active?Fall back to the declared modules, so navigation never blanks
EntitlementMay this tenant run it?Fail open by default
PermissionMay this user open it?Fail open by default

Failing open is deliberate: a control-plane read that failed must not lock a paying customer out of software they have paid for. Set onUnavailable: 'deny' per axis where absence genuinely means no. Anything guarding administration itself fails closed regardless.

How access control works

Sub-path exports

Each entry point names the environment it belongs to, so a server-only module cannot drift into a client bundle unnoticed.

Sub-pathContentsEnvironment
@cortejojicoy/admin-kitConfig helpers, types, pure logicAnywhere, including plain Node
…/clientAdminProvider, contexts, hooksClient
…/dataCRUD hooks, data provider, resource typesClient
…/accessEngine, <Can>, guardsClient
…/uiPanels, primitives, generated screensClient
…/serverSession, access gates, cookiesServer
…/middlewarecreateAdminMiddlewareEdge
…/styles.cssThe stylesheet

Full API reference

Start with a working install

admin-kit init scaffolds both config files, the middleware, the login route and one page per panel — then examples/app-router shows the same thing finished.