Architecture
Shiva is built around four interlocking ideas: modules, contracts, the container, and the event bus. Understanding how these fit together will make every other part of the docs make sense.
Overview
┌─────────────────────────────────────────────────────────────┐
│ FiveM Server │
│ │
│ ensure shiva-db ← DB driver (must be first) │
│ ensure shiva-core ← Framework engine │
│ ensure [modules...] ← Feature modules │
│ ensure shiva-boot ← Boot trigger (must be last) │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ shiva-core │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Module A │ │ Module B │ │ Module C │ │ │
│ │ │ Services │ │ Services │ │ Services │ │ │
│ │ │ Models │ │ Models │ │ Models │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ └───────────────┴───────────────┘ │ │
│ │ │ │ │
│ │ ┌─────────▼──────────┐ │ │
│ │ │ IoC Container │ │ │
│ │ │ (Contract bindings)│ │ │
│ │ └─────────┬──────────┘ │ │
│ │ │ │ │
│ │ ┌─────────▼──────────┐ │ │
│ │ │ Event Bus │ │ │
│ │ └────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘Layers
shiva-fw (Foundation)
Pure Lua 5.4 utilities with no FiveM dependencies: the container, event bus, error types, validators, collections, and string/number/table helpers. This layer is unit-testable without a running server.
shiva-db (Database Driver)
A FiveM resource that wraps MySQL/MariaDB with connection pooling and a clean async/sync export API. Must be the first resource ensured — shiva-core and all modules depend on it for all database queries.
shiva-core (Runtime)
The FiveM runtime. Bootstraps the container, loads modules, manages the 7-phase lifecycle, provides the bridge between Lua and FiveM native calls, and hosts the single NUI application.
Modules (Features)
Everything else is a module. A module is a directory that:
- Declares its contract bindings (
provides) - Declares its dependencies (
requires) - Registers services, models, and event handlers
- Has its own config, migrations, and locales
shiva-boot (Boot Trigger)
A minimal FiveM resource containing only sv_trigger.lua. It must be the last resource ensured. When FiveM starts it, it tells shiva-core to begin the 7-phase boot pipeline — guaranteeing all module resources are fully loaded before boot starts.
The Container
The IoC (Inversion of Control) container is the glue. Modules don't call each other directly. They request a contract from the container, and the container resolves which implementation to use.
The Event Bus
Cross-module communication happens through typed events. A module emits an event; any other module that cares can subscribe. No direct coupling.
Boot Sequence
When shiva-boot starts, shiva-core runs the following 7-phase pipeline:
Phase 1 — Core Init → Logger, container, config, and DB connection ready
Phase 2 — Module Discovery → Scans all ensured resources for shiva module manifests
Phase 3 — Dependency Resolution → Builds a DAG, validates no cycles, topological sort
Phase 4 — Validation → Config schemas validated, conflict checks run
Phase 5 — Migration → Pending DB migrations run in dependency order
Phase 6 — Service Registration → Each module's boot.lua runs, contracts validated
Phase 7 — Module Boot → Events/commands/schedulers register; fires `framework:ready`The framework:ready event signals that all modules are fully operational.
NUI Architecture
shiva-core hosts a single NUI application (React + Vite) shared by all modules. Modules interact with it in two tiers:
- Tier 1 (Data-driven): Notifications, progress bars, context menus, skill checks — Lua sends data, the NUI renders it. No custom JS required.
- Tier 2 (Custom panels): Modules ship their own JS bundles (inventory UI, phone, MDT). The NUI host loads them into one of four render layers:
hud,overlay,panel,modal.