# What NXM modules are

> An NXM module is a business module you install into a tenant as one package file, with its own records, lists, pages, roles, actions and tools for the AI Assistant. This page explains what a module consists of, how it differs from built-in modules and apps, and how a package becomes a running module.

Take a law firm that wants to run its case files in nexxus: files with a number, a client and an opposing party, the documents that belong to each file, letters waiting for a lawyer's approval, and court deadlines nobody may miss. None of that ships with nexxus. A developer describes these business objects, their screens and their rules in one package. An administrator uploads the package, reads what it brings and what it wants to access, agrees and installs it. From that moment the firm's staff find a new section in their menu, lists and record pages work like everywhere else in nexxus, and the AI Assistant can search and draft in the new records with the rights of the person asking.

That package is an **NXM module**. The name comes from its file extension, `.nxm`. In the app, the catalogue of these files is called <Ui>Packages</Ui>.

<Screenshot src={shot_nxm_12} url="/x/acme.leihgeraete/geraet" alt={"Package modules in the menu area Organisation"} caption={"Each package gets a section of its own, after the built-in sections."} />

## What a module brings

A package describes a business area. Most of it is declared in one manifest file, `module.json`, and nexxus builds the screens and checks from it. Only what cannot be declared is written as code, and that code never runs inside nexxus.

<CardGrid>
  <Card title="Business objects" icon="database">
    Entities such as a case file or a deadline, with typed fields: text, numbers, dates, choice lists, and references to partners, users, documents or other records of the module. Running numbers like `2026/0184` are assigned by nexxus.
  </Card>
  <Card title="Lists and record pages" icon="list-format">
    Declared, not programmed. nexxus renders lists with search, filters and sorting, and record pages with a <Ui>Data</Ui> tab, edit mode and related lists.
  </Card>
  <Card title="Custom views" icon="window">
    Pages, record tabs and dialogs written as one self-contained HTML file each. They run in a sandbox and reach data only through the view SDK, with the rights of the person looking.
  </Card>
  <Card title="Actions" icon="approve-check">
    Workflow steps such as "lend", "approve" or "complete", with conditions, a permission of their own and an optional confirmation. The server checks every condition again.
  </Card>
  <Card title="Permissions and roles" icon="padlock">
    Each entity brings a read and a write permission, the module adds its own, and its roles appear in the role editor. Nobody gets a role automatically.
  </Card>
  <Card title="AI Assistant" icon="comment">
    Tools to search, read, create and change records, instructions installed as a skill, and example prompts for each view. Every writing tool asks in the chat first.
  </Card>
  <Card title="Module services" icon="server">
    Optional programs outside nexxus that compute, react to changes or read documents. They work with short-lived tokens and only with the data the administrator agreed to.
  </Card>
  <Card title="Versions" icon="code-branch">
    Every version is immutable. An update can rename values or fields in stored records, and nexxus shows a dry run of every change before it happens.
  </Card>
</CardGrid>

## Built-in module, NXM module or app

nexxus can be extended in more than one way. The right choice depends on what you are building and who builds it.

| | Built-in module | NXM module | App |
|---|---|---|---|
| **What it is** | A part of nexxus itself, such as projects, timesheets or Files | A business module delivered as a `.nxm` package | A small tool whose documents are files, delivered as `.nxa` |
| **Who builds it** | The nexxus team | Developers | Business teams with the AI Assistant, or developers |
| **Who installs it** | Nobody: it comes with every instance. Administrators can switch whole business areas off | Administrators, per tenant | Anyone for themselves, administrators for the whole tenant |
| **Where its data lives** | In nexxus | In nexxus's record store, as typed records with indexes | In a document in Files |
| **Who may see what** | Permissions defined by nexxus | Its own permissions and roles | The sharing of the document |
| **AI Assistant** | Built-in tools | Its own tools, instructions and example prompts | The general app tools |
| **Example** | Projects with their timesheets | Case files and deadlines of a law firm | A Kanban board for onboarding new staff |

Choose an **NXM module** when you need records that many people work on in lists, with rights, workflow steps and a place in the menu, and when the module will grow in versions that update stored data. Choose an **app** when the result is a document that people open, edit and share. When something must become part of nexxus for every customer, it is a built-in module, and that is work for the nexxus team.

Installed packages also show up on the <Ui>Modules</Ui> tab next to the built-in modules, marked with the chip <Ui>Package</Ui>, with their version and changelog.

<Screenshot src={shot_nxm_01} url="/modules" alt={"The module list with installed packages and the changelog of the tutorial package"} caption={"Installed packages appear next to the built-in modules, with version and changelog."} />

## One rule: package code never runs inside nexxus

Every platform that lets customers extend a shared installation has to decide where their code runs. nexxus keeps it out of its own process, and a package therefore works on three levels:

<Hub
  inputsLabel="The package brings"
  inputs={[
    { icon: 'file-cog', title: 'Declarations', text: 'Entities, fields, lists, record pages, menu entries, actions, roles' },
    { icon: 'app-window', title: 'Custom views', text: 'One HTML file per page, tab or dialog' },
    { icon: 'server-cog', title: 'Module service', text: 'Optional, runs outside nexxus' },
  ]}
  core={{
    title: 'nexxus',
    text: 'Interprets the declarations, hosts the views in a sandbox, calls the service with signed tokens',
    items: ['Rights', 'Records', 'Consent', 'Tenants'],
  }}
  outputsLabel="People get"
  outputs={[
    { icon: 'layout-list', title: 'Menu, lists, records', text: 'Rendered by nexxus like every other module' },
    { icon: 'panels-top-left', title: 'Pages and dialogs', text: 'With the rights of the person looking' },
    { icon: 'bot', title: 'Tools for the AI Assistant', text: 'Writing tools ask before they act' },
  ]}
  caption="Declarations are data, views are sandboxed, services live outside. Every request passes the same rights check on the server."
/>

1. **Declarations.** Entities, fields, lists, record pages, menu entries, actions, roles and settings are data in `module.json`. nexxus reads them and builds the screens, the validation and the API. Most modules need little else.
2. **Custom views.** Where a list and a form are not enough, a package brings its own screens as HTML files. nexxus shows each one in a sandboxed frame without network access. The view asks nexxus for data through the view SDK, and nexxus answers with the rights of the person looking at it. See [Views and the view SDK](/modules/views/).
3. **Module services.** Work that needs a program, such as computing court deadlines or reading PDFs, runs in a service outside nexxus. nexxus calls it with a short-lived signed token, and the service calls back with a token that carries only the access the administrator agreed to. See [Module services](/modules/services/).

The result for your tenant: a package cannot read data it was not given and cannot bypass a permission, because the checks run on the server and never in the package.

## What every module gets from nexxus

A package does not have to build what nexxus already does well:

- **Rights.** Every list, record, action, view and tool checks the person's permissions on the server. Administrators pass every check.
- **Consent.** Before a package may touch data outside its own (partners, users, documents) or call a service, the administrator ticks each item in the install dialog. An update that wants more asks again.
- **Tenants.** Each tenant installs its own packages. Records of one tenant are invisible to every other tenant.
- **Self-contained.** A package never builds on another package; what belongs together ships as one package. Switching a business area off does not hide a package either. Only deactivating or uninstalling it does. See [Packages are self-contained](/modules/structure/#packages-are-self-contained).
- **AI Assistant.** Packages do not bring a chat of their own. They feed the one assistant with tools, instructions and example prompts, and it knows which module, record and view the person has open.
- **Signatures.** Publishers sign packages with their own key, without registering it anywhere. Each tenant decides whether it trusts a key; a package from a key it does not trust yet can be uploaded and looked at, but not installed. Unsigned packages are refused unless the tenant or the operator of the instance allows them (development and demo setups do by default). See [Trust the publisher](/modules/publish/#trust-the-publisher).

## The lifecycle at a glance

<Flow
  steps={[
    { icon: 'package', title: 'Build', text: 'Write the manifest and views, pack the folder into a .nxm file, sign it.' },
    { icon: 'upload', title: 'Upload', text: 'An administrator uploads the file. nexxus checks it and lists every problem.', tone: 'cyan' },
    { icon: 'shield-check', title: 'Review and agree', text: 'The package page shows what it brings. The install dialog asks for consent and roles.', tone: 'lavender' },
    { icon: 'download', title: 'Install', text: 'Roles, sample data and menu entries appear. The module is active.' },
    { icon: 'refresh-cw', title: 'Update or remove', text: 'A newer version updates in place. Deactivating or uninstalling keeps or deletes the data.', tone: 'neutral' },
  ]}
  caption="Developers build the file. Administrators upload, install and update it under Administration > Operations > Modules, tab Packages."
/>

An installation is in one of three states, shown as chips in the catalogue:

| State | What it means |
|---|---|
| <Ui>Active</Ui> | The module is in the menu, its views and tools work. |
| <Ui>Deactivated</Ui> | Menu entries, pages and tools are gone for everyone. Data, roles and settings stay, and <Ui>Activate</Ui> brings everything back. |
| <Ui>Removed, data kept</Ui> | The module was uninstalled with its records kept. A later install attaches them again. |

Uninstalling with <Ui>Delete the data</Ui> removes the installation completely. How each step works is described in [Package, install and update](/modules/publish/). What happens to stored records is in [Data and upgrades](/modules/data-and-upgrades/).

## Terms

- **Package**: one version of a module as a `.nxm` file, a ZIP archive with the manifest, the changelog, views and data files.
- **Manifest**: the file `module.json` that declares everything the module consists of. See [Package structure](/modules/structure/).
- **Key**: the module's name, `<publisher>.<name>`, such as `curiaos.kanzlei`. Permissions, tools and routes are derived from it.
- **Entity**: a business object of the module, such as a case file. Its single entries are **records**.
- **View**: a list, a record page, or a custom HTML view. Custom views sit in a **slot**: a page, a record tab, a record dialog.
- **Action**: a workflow step on a record, with a condition and a permission.
- **Scope**: data outside the package that its actions and services may use, such as `core:partner:read`.
- **Installation**: one package installed in one tenant, with its version, consent and settings.
- **Module service**: a program outside nexxus that the module calls or that receives the module's events.

## Next steps

<CardGrid>
  <LinkCard title="Start with an invitation" description="Claude Code and one line from your invitation: tools, test tenant and a first module in about a minute." href="/modules/invitation/" />
  <LinkCard title="Build your first module" description="A small loan register from an empty folder to an installed module and an update." href="/modules/first-module/" />
  <LinkCard title="Package, install and update" description="The administrator's side: catalogue, consent, roles, updates and uninstall." href="/modules/publish/" />
  <LinkCard title="Case study: CuriaOS" description="One package for a law firm, with custom views and a deadline service." href="/modules/curiaos/" />
</CardGrid>