API
Server engine
createCMS options and calling the engine directly from loaders and jobs.
createCMS(options) returns { engine, router }. Options:
db: a Drizzle database over D1 or SQLitebucket: an R2-compatible bucket (storagefromvoid/storage); enables mediasite:{ specValidator, specGuide, themeSchema }hooks: named custom hooks for{ type: "custom", name }jsonSchemas: named zod schemas for json fieldscollections: extra collections defined in code, read-only to D1 and AImediaPath: where media is served, default/api/_media
The engine
Engine methods take the acting user first (or null) and return T | CMSError instead of throwing. REST, MCP, and your own code share the same checks.
import { CMSError } from "@interactive-inc/cms"
const engine = createSiteCMS().engine
const page = await engine.resolvePage(null, { path: "/blog/hello" })
if (page instanceof CMSError) return page
if (page === null) return notFound()
const published = await engine.processScheduledPublishes()
const delivered = await engine.processOutbox(deliverOutboxEvent)