Overview
Every ARI module follows a consistent structure. This makes modules predictable, easy to understand, and simple to share with others.
ARI ships with a Module Template (modules-core/module-template/) that serves as the reference implementation for all new modules. When you create a module with the /ari-create-module command, it uses this template as its foundation — so every module starts with the right patterns for authentication, database access, API routes, and security already in place.
What a Module Contains
A module is a self-contained unit that can include any combination of:
- Pages — Full page support within the ARI workspace
- API Routes — Dedicated endpoints for the module's data operations
- Database Tables — Module-specific tables with row-level security
- Dashboard Widgets — Optional cards on the main ARI dashboard
- Settings — Per-module configuration options
- Navigation — Automatic sidebar integration
Module File Structure
A typical module directory looks like this:
modules-core/my-module/
├── module.json # Module manifest (required)
├── app/
│ └── page.tsx # Main page component
├── api/ # API route handlers
├── components/ # React components
├── hooks/ # Custom React hooks
└── database/
├── schema.sql # SQL schema (runs on every module enable)
├── schema.ts # Drizzle ORM schema definitions
├── relations.ts # Drizzle relation definitions
└── uninstall.sql # Cleanup SQL (manual-only, not auto-run)
Important: schema.sql runs every time a module is enabled, so it must be idempotent (use CREATE TABLE IF NOT EXISTS, etc.). The uninstall.sql file is not run automatically — it is provided for manual cleanup if needed.
Module Manifest (module.json)
Each module has a module.json manifest that defines its metadata and behavior. Here is the full schema:
| Field | Type | Description |
|---|---|---|
id |
string | Unique module identifier |
name |
string | Display name |
group |
string | Category grouping (e.g. "Productivity", "Fitness") |
description |
string | Short description of the module |
version |
string | Semantic version number |
icon |
string | Lucide icon name for sidebar display |
enabled |
boolean | Whether the module is active by default |
fullscreen |
boolean | Use fullscreen layout instead of standard sidebar layout |
menuPriority |
number | Sort order in the sidebar (lower = higher) |
permissions |
object | Module capabilities (database, api, dashboard — all boolean) |
routes |
array | Custom route definitions |
dependencies |
object | Other modules or core features this module depends on |
database |
object | Database configuration |
dashboard |
object | Dashboard widget configuration |
settings |
object | Module-specific settings schema |
topBarIcon |
object | Add a quick-access icon to the top navigation bar (e.g. { "icon": "CheckSquare", "route": "/tasks", "tooltip": "Open Tasks" }) |
submenu |
object | Sidebar submenu component configuration |
publicRoutes |
array | Routes accessible without authentication |
Layout Options
Modules support two layout modes:
- Standard — Renders within the ARI sidebar layout. Best for most modules like Task Manager, Contacts, and Knowledge Manager.
- Fullscreen — Takes the entire viewport. Best for immersive experiences like games, canvases, or visualization tools. Set
"fullscreen": trueinmodule.json.
Module Directories
ARI loads modules from two directories:
| Directory | Managed By | Survives Upgrade | Priority |
|---|---|---|---|
modules-core/ |
Upstream | No (overwritten on upgrade) | Lower |
modules-custom/ |
You | Yes | Higher |
Custom overrides core: If a module with the same id exists in both modules-core/ and modules-custom/, only the version in modules-custom/ is loaded. This lets you fork and customize any core module without modifying the original.
Module Registration
ARI uses a registry system to manage modules. When you create a module with the /ari-create-module command, registration is handled for you automatically. The registry is regenerated at build time by scanning the modules-core/ and modules-custom/ directories, so your module is picked up and available in the sidebar and routing.
Sharing Modules
Because modules are self-contained directories with a consistent structure, they are easy to share. You can copy a module folder to another ARI instance, share it with the community, or fork an existing module and customize it.
See Creating Modules for how to build your own.