Skip to content

Framework packages (npm)

Xentium is a framework, and this CMS is the first app built on it. We publish the framework layer to npm under the @xentium scope (public, MIT), so you can build other things on it too.

These are the packages core runs on. We don’t keep a separate “public API” that lags behind what we use ourselves.

Package What you get
@xentium/contracts shared types, permission keys, pagination and the XEC error-code registry
@xentium/errors XentiumError, the XEC registry and the Express error middleware
@xentium/server-kit settings with a TTL cache, pagination, encryption at rest, rate limiting, upload validation, storage
@xentium/auth minting and verifying tokens, argon2 hashing, a revocation denylist, request guards
@xentium/plugin-engine manifest validation, the DDL-only migration guard, the plugin registry and router
Terminal window
pnpm add @xentium/errors @xentium/server-kit

We’re still in prerelease, so these go out under the alpha dist-tag. Pin it:

Terminal window
pnpm add @xentium/errors@alpha

Anything with a dependency is a factory. Nothing grabs a module-level singleton, so your app passes in its own database, secret, Redis client or filesystem root:

import { createErrorMiddleware } from "@xentium/errors";
import { createSettings } from "@xentium/server-kit";
app.use(createErrorMiddleware({ isProd, logger, persist }));
const settings = createSettings({
get: (key) => db.setting.findUnique({ where: { key } }),
getMany: (keys) => db.setting.findMany({ where: { key: { in: keys } } }),
});

The rule we hold these packages to: a framework package doesn’t know what a user, an article or a page is. So the layout/block system, appearance and everything else that’s CMS-specific stays in apps/ and isn’t published.

[!IMPORTANT] @xentium/plugin-sdk isn’t on npm yet. It’s the authoring contract you need, and we’re holding it back on purpose: we’re splitting it into a generic half and a CMS-specific half, which is a breaking change. We’d rather make you wait than publish a version we already know we’ll break.

Until then, take it from the repo: copy packages/plugin-sdk/src/index.ts into your plugin, or add the repo as a git dependency. It’s types only, so nothing extra ships at runtime either way.

The rest of the framework is useful in a plugin today: @xentium/contracts for permission keys and XEC codes, and @xentium/errors so your plugin’s errors come back in the same shape as ours.

You don’t need @xentium/server-kit, @xentium/auth or @xentium/plugin-engine in a plugin. The host already runs them, and ctx.host gives you what it has: prisma, queues, logger, the auth middleware. If you install your own copy, you get a second instance that isn’t connected to anything.

The full walkthrough is in the Plugin development guide.