Quorium
Quorium
Navigation
Why Quorium What It Does How It Works Permissions vs Caps Packages Core API Adapters Module Structure Design Principles Where It Fits Roadmap
@nextera.one/quorium-* · 8 packages
Framework-agnostic runtime governance

Deterministic Runtime Governance
for Modular Frontends

Quorium composes routes, navigation, and module activation from permissions, feature flags, and capability contracts — deterministically. Framework-agnostic core. Adapters for Vue, Quasar, React, Svelte & Framework7.

Etymology

Quorium combines Quorum — the minimum agreement needed to act — and Core.

A quorum-based runtime that determines what is allowed to exist in a frontend system — based on rules, permissions, and capabilities.

projects.module.ts
import { defineModule } from '@nextera.one/quorium-core'
import { SESSION_TOKEN } from '../core/tokens'

export const ProjectsModule = defineModule({
  id: 'projects',
  version: '1.0.0',
  requires: [SESSION_TOKEN],
  provides: [PROJECTS_SERVICE_TOKEN],
  routes: [
    { name: 'projects.list', path: '/projects', permission: 'projects.read',
      nav: { label: 'Projects', icon: 'folder_open', order: 10 } },
    { name: 'projects.new', path: '/projects/new', permission: 'projects.write' }
  ],
  isEnabled(ctx) {
    return ctx.enabledModules.has('projects');
  },
  setup(ctx) {
    // Wire service via DI — adapter-specific (e.g. ctx.app.provide for Vue)
  }
})
One file. Typed DI. Permission-governed routing. Feature-flag gated. That's a Quorium module.

Why Quorium Exists

Large frontend applications eventually collapse into structural drift. Quorium introduces runtime composition — your app decides at runtime what is allowed to exist.

The Problem
The Collapse of Large SPAs
cancelRoutes are static and never truly removed
cancelPermissions only hide UI, not structure
cancelFeature flags don't control route existence
cancelModules import each other directly
cancelLogin/logout leaves stale routes active
The Answer
Quorium Governance
check_circleRoutes generated dynamically from permissions
check_circleTyped DI tokens isolate every module boundary
check_circleCross-module communication via capability contracts
check_circleFeature flags centrally governed per tenant & edition
check_circleSession change triggers full recomposition — zero reload
It's not a UI kit. It's not just a folder pattern.
It's a governed execution layer
for modern enterprise frontends.
Without Quorium
if (hasPermission('projects.create')) {
  router.push('/projects/new')
}
Routes still exist in the router
Navigation still renders the link
Module still loads its code
Structure drifts from intent
With Quorium
const runtime = createRuntime({ modules })
const result = runtime.compose(context)
applier.apply(router, result.routes)
Route is not registered
Navigation is not generated
Module may not activate
Existence is governed

What Quorium Actually Does

A framework-agnostic runtime engine with five concrete responsibilities.

Filters Routes by Permission

Routes are filtered before registration via filterRoutesByPermissions(). If the permission is missing, the route does not exist — not hidden, not guarded, absent.

Activates Modules by Feature Flag

Modules only activate when enabledModules contains their id. Disabled modules contribute zero routes, zero navigation, zero state.

Validates Capability Dependencies

Each module declares requires and provides via typed symbols. Missing dependencies surface in missingCapabilities — caught before wiring.

Rebuilds Router on Session Change

Login, logout, or role change triggers runtime.compose() again. Old routes are removed. New routes are registered. Zero page reload.

Generates Navigation from Routes

buildNavigation() derives navigation items from the composed route specs. One source of truth — no duplicate menu configuration.

Nothing Exists Unless Admitted

This is the governing principle. Routes, navigation, and modules only exist if explicitly admitted by permissions, flags, and capabilities.

How It Works

Every module passes through a deterministic pipeline. Core stays pure TypeScript — adapters translate the result into your framework.

1
Feature Flags
Each module declares an optional id. The runtime checks enabledModules — disabled modules are excluded before any further processing.
feature flag
2
Permission Filtering
filterRoutesByPermissions() walks every module's route tree and strips any route whose meta.permissions the current user doesn't hold. The shape of the tree is preserved.
permissions
3
Capability Validation
validateCapabilities() checks that every requires token declared by a module is satisfied by a provides token from another. Unsatisfied contracts throw before any adapter runs.
DI contracts
4
runtime.compose() → CompositionResult
Merges all admitted modules into a single CompositionResult — a plain object holding the final route tree, flat navigation items, capability map, and merged metadata. No framework code runs here.
core engine
5
Framework Adapter
A thin adapter converts the framework-agnostic CompositionResult into the exact structures your framework expects.
Vue Quasar React Svelte Framework7
adapter layer
6
Router + Navigation + UI
Routes are registered, nav items are rendered, drawer menus are populated — all driven by the same core output, regardless of framework.
output
Core is pure TypeScript No framework in core Adapters are thin layers
@nextera.one/quorium-core
Framework-Agnostic Engine
createRuntime() defineModule() filterRoutesByPermissions() validateCapabilities() buildNavigation() compose()
Framework Adapters
Thin Adapter Layers
Vue coreToVueRoutes() VueRouteApplier
Quasar toQuasarDrawerItems()
React coreToReactRoutes() ReactRouteManager
Svelte coreToSvelteRoutes()
F7 coreToF7Routes() F7RouteManager

Permissions vs Capabilities

Two orthogonal systems — one governs what a user can visit, the other governs what a module can depend on.

Permissions
User Access Rights
A set of string tokens describing what the current user is allowed to do. Routes declare which permissions are required via meta.permissions; filterRoutesByPermissions() strips any route the user can't access — before the adapter ever runs.
Example tokens
admin billing:read reports:write superuser
// route meta
meta: {
  permissions: ['billing:read']
}

// runtime call
filterRoutesByPermissions(
  routes, userPermissions
)
When checked
Step 2 of the composition pipeline — after feature flags, before capability validation.
Capabilities
Module DI Contracts
Typed tokens that model inter-module dependencies. A module declares what it provides and what it requires. validateCapabilities() ensures every requirement is satisfied at compose-time — before any route is registered.
Example tokens
AuthService UserStore AnalyticsProvider FeatureFlags
// module definition
defineModule({
  requires: [AuthService],
  provides: [UserStore],
  routes: [...]
})

// runtime call
validateCapabilities(modules)
When checked
Step 3 of the composition pipeline — after permission filtering, before compose() runs.
Permissions answer the question "Can this user see this route?"  |  Capabilities answer "Does this module have what it needs to function?"
Both are resolved by pure functions in @nextera.one/quorium-core — no framework, no side effects.

The Quorium Ecosystem

8 packages. One architecture. Core stays pure TypeScript — adapters bridge to your framework.

Vue Adapter
@nextera.one/quorium-vue

Vue Router 4 adapter. Converts CoreRouteSpec to RouteRecordRaw, dynamic route add/remove via VueRouteApplier, typed DI with provideToken / useToken.

React Adapter
@nextera.one/quorium-react

React Router v6/v7 adapter. Converts CoreRouteSpec to RouteObject with ReactRouteManager for declarative route recomputation.

Svelte Adapter
@nextera.one/quorium-svelte

Svelte / SvelteKit adapter. Converts to SvelteRouteRecord with nested or flattenSvelteRoutes() for single-depth routers.

Framework7 Adapter
@nextera.one/quorium-framework7

Framework7 adapter. Converts to F7RouteRecord with asyncComponent and F7RouteManager for mobile-first apps.

CLI
@nextera.one/quorium-cli

Scaffold and validation tool. Commands: quorium init, quorium new, quorium add-route, quorium validate, quorium gen.

Decorators
@nextera.one/quorium-decorators

Optional decorator-based DX. @QModule and @QRoute decorators that generate CoreModule and RouteSpec from class metadata.

npm install
# Required — the core runtime engine
npm install @nextera.one/quorium-core

# Pick your framework adapter (one or more)
npm install @nextera.one/quorium-vue         # Vue 3 + Vue Router 4
npm install @nextera.one/quorium-quasar      # Quasar 2 (extends vue adapter)
npm install @nextera.one/quorium-react       # React 18/19 + React Router 6/7
npm install @nextera.one/quorium-svelte      # Svelte / SvelteKit
npm install @nextera.one/quorium-framework7  # Framework7

# Optional tooling
npm install @nextera.one/quorium-cli         # CLI: init, new, add-route, validate, gen
npm install @nextera.one/quorium-decorators  # @QModule / @QRoute decorators

Core API in 20 Seconds

Deterministic input → deterministic route tree. Same context always produces the same output.

@nextera.one/quorium-core
import { createRuntime, defineModule, buildNavigation } from '@nextera.one/quorium-core'

// 1. Define a module with typed CoreModule interface
const ProjectsModule = defineModule({
  id: 'projects',
  requires: [SESSION_TOKEN],
  provides: [PROJECTS_SERVICE_TOKEN],
  routes: [
    { name: 'projects.list', path: '/projects', permission: 'projects.read',
      nav: { label: 'Projects', icon: 'folder_open', order: 10 } },
    { name: 'projects.new',  path: '/projects/new', permission: 'projects.write' }
  ]
})

// 2. Create runtime and compose with current context
const runtime = createRuntime({ modules: [ProjectsModule] })

const composed = runtime.compose({
  permissions:    new Set(['projects.read']),
  enabledModules: new Set(['projects']),
  capabilities:   new Set([SESSION_TOKEN])
})

// 3. CompositionResult — deterministic output
composed.routes              // CoreRouteSpec[] — permission-filtered
composed.activeModules       // ['projects']
composed.missingCapabilities  // [] — broken contracts surface here

// 4. Build navigation from composed routes
const navItems = buildNavigation(composed.routes)
// [{ name: 'projects.list', path: '/projects', label: 'Projects', icon: 'folder_open' }]
This is real API from the codebase. Types: CoreModule, RuntimeContext, CompositionResult, CoreRouteSpec.

Adapter Examples — Real API

The core composes. The adapter applies. Every example below uses real exports from the packages.

Vue + Quasar (Premium Adapter)
boot/quorium.ts
import { createRuntime, buildNavigation } from '@nextera.one/quorium-core'
import {
  coreToVueRoutes, VueRouteApplier, runModuleSetups,
  toQuasarDrawerItems, notifyMissingCapabilities
} from '@nextera.one/quorium-quasar'

const runtime  = createRuntime({ modules })
const applier  = new VueRouteApplier()
const composed = runtime.compose(context)

// Convert to Vue routes & apply
const vueRoutes = coreToVueRoutes(composed.routes, resolveComponent)
applier.apply(router, vueRoutes)

// Run admitted module setup hooks (DI wiring)
runModuleSetups(modules, { ...context, app }, composed.activeModules)

// Quasar drawer navigation — auto-generated
const nav = buildNavigation(composed.routes)
const drawerItems = toQuasarDrawerItems(nav)

// Surface missing capability warnings via Quasar Notify
notifyMissingCapabilities(composed.missingCapabilities, { notify: $q.notify })
React Adapter
app-router.tsx
import { createRuntime } from '@nextera.one/quorium-core'
import { ReactRouteManager, coreToReactRoutes } from '@nextera.one/quorium-react'

const runtime = createRuntime({ modules })
const manager = new ReactRouteManager()
const composed = runtime.compose(context)

// Compute React Router route objects
const routeObjects = manager.compute(composed.routes, resolveComponent)

// Use with createBrowserRouter or RouterProvider
const router = createBrowserRouter(routeObjects)
Svelte Adapter
routes.ts
import { createRuntime } from '@nextera.one/quorium-core'
import { coreToSvelteRoutes, flattenSvelteRoutes } from '@nextera.one/quorium-svelte'

const runtime  = createRuntime({ modules })
const composed = runtime.compose(context)

// Nested routes (svelte-routing)
const nested = coreToSvelteRoutes(composed.routes, resolveComponent)

// Or flat routes (svelte-spa-router)
const flat = flattenSvelteRoutes(nested)

Recommended Module Structure

Every feature module follows the same governed pattern. API calls, business logic, state, pages, and the module entry point — each in its own layer.

src/modules/projects/
├── api/
│   ├── index.ts
│   └── projects.api.ts
├── facade/
│   ├── index.ts
│   └── projects.facade.ts
├── pages/
│   ├── index.ts
│   └── projects.route.ts
├── services/
│   ├── index.ts
│   └── projects.service.ts
├── stores/
│   ├── index.ts
│   └── projects.store.ts
└── projects.module.ts
Layer Responsibilities
api/
Typed HTTP client — all API calls for this module.
facade/
Cross-module surface. The only thing other modules can import (via DI tokens).
pages/
UI pages & route definitions. List, detail, create views.
services/
Business logic layer. Orchestrates API + store + policy.
stores/
State management (Pinia, Zustand, etc.) — scoped via DI tokens.
projects.module.ts
Module entry point. Declares routes, requires/provides, setup hook, isEnabled gate.
projects.module.ts (full example)
import { defineModule } from '@nextera.one/quorium-core'
import type { VueModuleRuntimeContext } from '@nextera.one/quorium-vue'
import { SESSION_TOKEN, PROJECTS_SERVICE_TOKEN } from '../../core/tokens'
import { ProjectsService } from './services'

export const ProjectsModule = defineModule<VueModuleRuntimeContext>({
  id: 'projects',
  version: '1.0.0',
  requires: [SESSION_TOKEN],
  provides: [PROJECTS_SERVICE_TOKEN],
  routes: [
    {
      name: 'projects.list',
      path: '/projects',
      permission: 'projects.read',
      meta: { component: () => import('./pages/ProjectsListPage.vue') },
      nav: { label: 'Projects', icon: 'folder_open', order: 10 }
    },
    {
      name: 'projects.new',
      path: '/projects/new',
      permission: 'projects.write',
      meta: { component: () => import('./pages/ProjectsNewPage.vue') }
    }
  ],
  setup(ctx) {
    // Wire service into Vue DI — available via useToken(PROJECTS_SERVICE_TOKEN)
    ctx.app.provide(PROJECTS_SERVICE_TOKEN, new ProjectsService())
  }
})

Design Principles

Deterministic Composition

Same input always produces the same output. No side effects. No surprises.

Explicit Module Boundaries

No cross-module imports. Dependencies flow through typed capability tokens.

Capability-Based Dependencies

Modules declare requires and provides. Missing tokens are caught before activation.

Permission-Driven Existence

Routes don't exist unless the permission exists. Not hidden — structurally absent.

Runtime Rebuild Consistency

Session change → full recomposition. The route tree always reflects current reality.

No Hidden Coupling

Every dependency is explicit. Every connection is visible. No implicit global state.

What Quorium Is Not

Clarity builds trust. Here's what Quorium does not do.

Not a UI Component Library

No buttons, no inputs, no layouts. Use Quasar, Vuetify, MUI, or whatever you want.

Not a Router Replacement

Quorium composes routes for your router. Vue Router, React Router, SvelteKit — they still do the routing.

Not a State Manager

Use Pinia, Zustand, or anything else. Quorium governs structure, not state.

Not a Micro-Frontend Framework

No iframes, no module federation. Quorium works inside a single application.

Not a Build Tool

No webpack config, no vite plugins. Quorium is pure runtime — zero build-time magic.

It Governs Structure

Nothing more. Admission, composition, and consistency — at runtime. Framework agnostic.

Where Quorium Fits

Quorium brings backend-level discipline to frontend composition.

Backend
NestJS → Module System
Guards → Authorization
Frontend
Quorium → Structural Admission
Vue / React / Svelte / F7 → Rendering

Designed For

  • Enterprise admin panels
  • Multi-tenant SaaS platforms
  • Role-based systems
  • Edition-based products (Free / Pro / Enterprise)
  • Large applications with 20+ feature modules
  • Teams that want discipline without losing flexibility

Not Just Structure — Governance

Quorium treats the frontend like a governed system:

  • Feature boundaries & capability contracts
  • Module manifest with version tracking
  • Route + permission absolute alignment
  • Centralized runtime decision logic
  • Framework-agnostic core with targeted adapter layers

Quick Start

Install the packages and compose your first governed runtime in 4 steps.

1
Install Packages

Install the core runtime and the adapter for your framework.

npm install @nextera.one/quorium-core

# Pick your framework adapter
npm install @nextera.one/quorium-vue         # Vue 3 + Vue Router 4
npm install @nextera.one/quorium-quasar      # Quasar 2 (includes vue adapter)
npm install @nextera.one/quorium-react       # React 18/19 + React Router 6/7
npm install @nextera.one/quorium-svelte      # Svelte / SvelteKit
npm install @nextera.one/quorium-framework7  # Framework7

# Optional
npm install @nextera.one/quorium-cli         # CLI scaffolding tool
npm install @nextera.one/quorium-decorators  # @QModule / @QRoute decorators
2
Define a Module

Declare routes, permissions, capabilities, and an optional feature-flag gate using defineModule().

import { defineModule } from '@nextera.one/quorium-core'

export const ProjectsModule = defineModule({
  id: 'projects',
  requires: [SESSION_TOKEN],
  provides: [PROJECTS_SERVICE_TOKEN],
  routes: [
    { name: 'projects.list', path: '/projects', permission: 'projects.read',
      nav: { label: 'Projects', icon: 'folder_open', order: 10 } },
    { name: 'projects.new',  path: '/projects/new', permission: 'projects.write' }
  ],
  setup(ctx) {
    ctx.app.provide(PROJECTS_SERVICE_TOKEN, new ProjectsService())
  }
})
3
Create the Runtime & Compose

Pass the RuntimeContext — permissions, enabled modules, and capabilities — and get a deterministic CompositionResult.

import { createRuntime } from '@nextera.one/quorium-core'

const runtime  = createRuntime({ modules: [ProjectsModule] })
const composed = runtime.compose({
  permissions:    new Set(['projects.read']),
  enabledModules: new Set(['projects']),
  capabilities:   new Set([SESSION_TOKEN])
})

// composed.routes              → permission-filtered CoreRouteSpec[]
// composed.activeModules       → ['projects']
// composed.missingCapabilities → []
4
Apply to Your Router

Use the framework adapter to apply the composed routes.

// Vue / Quasar
import { coreToVueRoutes, VueRouteApplier } from '@nextera.one/quorium-vue'

const applier   = new VueRouteApplier()
const vueRoutes = coreToVueRoutes(composed.routes, resolveComponent)
applier.apply(router, vueRoutes)

// React
import { ReactRouteManager } from '@nextera.one/quorium-react'
const manager = new ReactRouteManager()
const routes  = manager.compute(composed.routes, resolveComponent)

// Svelte
import { coreToSvelteRoutes } from '@nextera.one/quorium-svelte'
const routes = coreToSvelteRoutes(composed.routes, resolveComponent)

// Role or flag change → recompose → reapply. Done.
Done. Same context always produces the same route tree — deterministically.

Status & Roadmap

Current
v0.3
Internal stable kernel. Deterministic compose + filtering + capability validation. 8 published packages.
v0.6
Public preview. Full docs + starter templates. CLI scaffolding.
v0.9
Hardening. Manifest validation. Performance baseline. Remote plugin loading.
v1.0
Stable. API freeze. SemVer. Production deployment. Compatibility policy.

Quorium is a framework-agnostic runtime that deterministically composes frontend structure from permissions, feature flags, and capability contracts. Adapters for Vue, Quasar, React, Svelte, and Framework7.

Clean. Precise. Credible.
Quorium
Deterministic Runtime Governance for Modular Frontends.
Packages: @nextera.one/quorium-core · quorium-vue · quorium-quasar · quorium-react · quorium-svelte · quorium-framework7 · quorium-cli · quorium-decorators
© 2026 Quorium. Open Source.