[data-reveal]{opacity:1!important;transform:none!important}
Interfaces
Interfaces

The DMS interface

One public package, @antelopejs/interface-dms, holds every contract a module uses — its subpaths, domain by domain.

Overview

The DMS ships one public AntelopeJS interface package, @antelopejs/interface-dms. Everything a module needs to declare pages, build components, authenticate a request, send a notification or render an HTML template comes from that single package, through a subpath named after the domain it belongs to. Never reach the surface through the runtime package @antelopejs/dms.

{
  "dependencies": {
    "@antelopejs/interface-dms": ">=0.0.1 <1.0.0"
  }
}

This section is the contract reference: the exact symbol names, options and return types, grouped by domain. The DMS guide covers the same ground task by task, organised around what you are building.

If you are learning the DMS, start with the Quickstart and Pages & components. Return here when you need an import path, a signature, or the exact behavior of an option; you do not need to read every domain before building a page.

TaskGuide with examplesContract reference
Build a page and choose its layoutPages & componentsPages and modules, Layout
Add workspace settingsSettings pagesPage access
Protect a route and scope its dataAuth & tenancyAuthentication, Tenancy
Extend another module's screenPage extensionsExtend a page

Separately published extension interfaces have their own module interface references, including Builder. This page covers @antelopejs/interface-dms itself.

One installed copy

The host and every module must resolve the same installed copy of @antelopejs/interface-dms. The package holds live state, not just types: the page, category and extension registries, the permission tree, the hook registry, the data-type and block registries and the component slot resolvers. A second copy gets its own empty registries: pages register into a tree nobody reads, permissions never reach the roles form, and hooks never fire, without any error. @antelopejs/core checks this before constructing modules and fails with Incompatible interface package resolution when a module resolves another copy.

Depend on the package with a wide range, raising the lower bound to the version you need rather than pinning an upper one, so package managers can deduplicate, and never vendor or bundle it into a module. @antelopejs/dms, which implements the interface, is the exception: it caps its range below the next minor, so a breaking minor never reaches an older DMS.

The runtime also hands a module a per-context view of the values it receives through an interface, so reference equality does not survive the round trip. Compare registrations on a field, never with ===, and compare plain data rather than the views themselves: isDeepStrictEqual and assert.deepStrictEqual refuse two views that hold equal values.

The Domains

DomainWhat it is forImport prefix
CorePages, modules, components, permissions, tenancy, invites, hooks, realtime, quick actions and layout banners.@antelopejs/interface-dms and its root-level subpaths
AuthAuthentication decorators, token and session handling, and the user and session tables.@antelopejs/interface-dms/auth
BaseThe component vocabulary: forms, tables, charts, layout, trees, data types and the shared prop types.@antelopejs/interface-dms/base
NotificationsDeclaring notification categories and subjects, and building and sending notifications.@antelopejs/interface-dms/notifications
HTML RenderRegistering HTML templates and rendering them server-side.@antelopejs/interface-dms/html-render

Start with Core and Base: the first declares pages and the components they carry as serializable data, the second is the concrete set of components you fill those pages with. Auth resolves a request to a user, which the permission and tenant guards build on. The remaining two stand on their own and are used where you need them.

Subpath Map

Each subpath is its own entry point: importing one does not pull the others in, and the modules that register schemas or controllers as they evaluate are deliberately kept off the root barrel. Every domain's introduction carries the detailed map of its own subpaths; this is the whole set at a glance.

SubpathHoldsDomain
@antelopejs/interface-dmsThe root barrel over the core surface belowCore
/pagePages, categories, modules, layouts, page extensions, dynamic menus, frontend modulesCore
/componentComponent, ComponentBuilder, actions, watchesCore
/component-slotsRegisterComponentSlot, ComponentSlotResolver, SlotOptionsCore
/attachmentsSaveComponentFiles and its request, field and result typesCore
/permission-gateShared PermissionGate fields for permission-filtered UIBase
/permissionsThe permission registry and the permission computationCore
/permissions-resolverRegistering and running permission resolversCore
/guardsAuthUserWithPermission, AuthTenantOwner, AuthTenantMemberCore
/constantsSchema names and the default tenantCore
/db, /db/models, /db/tablesThe Tenant, TenantMember, Role and UserInvite tables and modelsCore
/request-tenantgetRequestTenantIdCore
/tenant-scoped-modelTenantScopedModelCore
/tenant-accessTenant access gatesCore
/tenant-ownershipMembership and ownership writesCore
/tenant-lifecycleProducer admission and permanent closure before tenant deletionCore
/data-controllersThe built-in members and roles data controllersCore
/invitesInviting a user into a tenantCore
/invite-extensionsInvite form contributions, validation, delivery and availabilityCore
/invite-resolutionDurable terminal decisions and retryable invite effectsCore
/hooksThe Hook enum, handlers and dispatchCore
/tenant-exportThe tenant export archive, contribution and manifest typesCore
/realtimePage topics, publishing and backend subscriptionCore
/quick-actionsCommand-palette entriesCore
/layout-bannersGlobal banners under the dashboard headerCore
/uploadsSigned upload tokens for the file and image fields of a serialized componentCore
/typesMaybePromise, the one shared type aliasCore
/api-base-url, /client-base-urlGetApiBaseUrl, GetClientBaseUrl: the public origins of the API and the dashboardCore
/client-ipgetClientIp, ResolveClientIp: a request's client address behind the trusted proxiesCore
/authAuthentication decorators, tokens, sessions, external identities, account mailAuth
/auth/db, /auth/db/models, /auth/db/tablesThe User, Session and UserExternalIdentity tables and modelsAuth
/baseThe component barrel: forms, tables, charts, cards, layout, treesBase
/base/typesBase props, colours, sizes, buttons, action targets, row-action rules, guardsBase
/base/formForm, the field and group shapes, FormComponents, FormEvents, the schema helpersBase
/base/table-viewTableView, @Column, TableViewRoutes, guards, row actionsBase
/base/data-typesDataType, the registration decorators, DefaultDataTypes, DefaultDataCompareTypes, StatusTypeBase
/base/…The per-component subpaths — chart, grid, stack, tab, tree, custom, layouts, helpers/…Base
/notifications, /notifications/typesCategories, subjects, the notification builder and its dispatch targetsNotifications
/html-renderRegisterHtmlTemplate, GenerateHtml and the template reference typesHTML Render

Beyond these entry points, built files are importable through the ./* export (@antelopejs/interface-dms/base/form-types). Moving or renaming a public path is a breaking change, like removing an export.

Importability does not make a declaration public. Paths under internal/, symbols tagged @internal, and internal namespaces are wiring between the interface and its implementation, not supported consumer APIs. This includes compatibility exports retained at old paths. Public types named by a supported signature remain part of its contract; use the documented entry points rather than calling internal proxies or raw writer helpers.

How to Read a Domain

Every domain folder opens with 1.introduction.md. It gives you the overview, the key features, the AntelopeJS packages the domain depends on, one runnable quick-start example, and the list of the folder's other pages.

The numbered pages after it are topic pages, ordered so that reading them front to back builds up. Each one starts with an overview, then works through the surface task by task with a code example per section and a table for anything that takes options. Every topic page ends with a link to the next one, so you can also follow a folder straight through from its introduction.

Read a topic page on its own when you already know which surface you need.