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

Architecture

Why the backend describes the UI, how the two processes fit together, and how a page reaches the screen.

The backend describes the UI, and a shared frontend renders it. That inversion shapes everything else: two runtime processes, and a well-defined path a page takes from your code to the screen.

The idea: the backend describes the UI

Most admin frameworks build screens on the frontend and call an API for data. The AntelopeJS DMS inverts that.

The backend declares both the screen and its data sources, as serializable data. A shared frontend reads that description and renders it. Adding an admin page is a backend-only change in almost every case.

This buys three things:

  1. One frontend, many modules. Every module's UI uses the same component vocabulary, so a single Nuxt app renders all of them — no per-module frontend build.
  2. The backend stays the source of truth. Components receive URLs to fetch from and submit to; the data and the permissions live with the backend code that defined the page.
  3. Composability. A page is a class, its components are static fields, and modules add pages. Everything is plain TypeScript values you can factor and reuse.

Two processes

The idea above maps onto two processes at runtime.

The backend is your project. It is a normal AntelopeJS project that loads the DMS framework module (@antelopejs-private/cms) next to your own modules. Everything you write — pages, DataControllers, routes — imports its building blocks from that module's interfaces/* subpaths.

The frontend is shared. acms (from @antelopejs-private/cms-nuxt) is a generic Nuxt 4 loader: every DMS project runs the same one, and none of it lives in your repo. At startup it asks the backend which Nuxt layers to load — the built-in dashboard layer plus whatever modules registered with AddNuxtLayer. From there, a single catch-all route renders the component tree the backend returns for each page.

That startup call dictates the ordering: start the backend, wait until it is ready, then the frontend. It also explains what you won't find in your repo: no frontend build, no per-page Vue — your screens exist only as the descriptions your backend serves.

Commands, ports, and how acms discovers the backend are operational details, covered in Project setup and Frontend CLI.

How a page reaches the screen

A single request flows from your backend page class through the frontend renderer and back to a controller route:

Request flow
@RegisterPage class            (your backend code)
  static form = Form({...})     ── builder produces a serializable component description
        │
        ▼
RegisterPage decorator          ── records the page in the page registry at import time
        │
        ▼
GET <page-url>/pagelayout       ── frontend fetches the page's component tree from the backend
        │
        ▼
catch-all route                 ── the built-in dashboard layer recursively renders the tree
                                   with the component vocabulary
        │
        ▼
component fetches its data      ── Form/TableView/Chart call their fetchUrl / submitUrl …
        │                          (routes declared on the page class or in src/routes/)
        ▼
controller route handler        ── returns JSON; auth enforced by the route's decorators

The key insight: the builder output is data, not a live component. Form({...}) does not render anything; it produces a description the frontend knows how to draw. That is why a backend edit changes the UI and why you rarely touch Vue.

How it sits on AntelopeJS

Nothing here replaces AntelopeJS — it uses it:

  • The DMS and every module are AntelopeJS modules loaded by the core.
  • Everything the DMS exposes, and everything a module exposes, is an AntelopeJS interface consumed as a package subpath.

So the DMS is "an AntelopeJS app that happens to be a DMS framework." When a question is really about interfaces, the CLI, or module wiring in general, it's an AntelopeJS question — see the AntelopeJS documentation. When it's about pages, components, DataTypes, auth, or the DMS services, it's here.