Demo mode - you’re exploring the template you’d buySkin:
ModulesIntegrations
← All posts

How the Module System Works

A deep dive into Sentido's module system - enabling and disabling features at both the JavaScript and .NET layers.

By Carl Mills

architecturemodulestutorial

One of the most requested features in app templates is the ability to ship a product and later enable new capabilities for specific customers - or switch them off globally until they're ready. Sentido's module system handles this elegantly across both layers of the stack.

What is a module?

A module is a named feature that can be switched on or off independently. Sentido ships with these modules:

| Module ID | Description | |---|---| | teams | Team management - invite members, assign roles | | admin-panel | Admin UI - view and manage all users and tenants | | ai | AI features placeholder | | analytics | Analytics dashboard placeholder |

Enabling modules

In your .env file, set ENABLED_MODULES to a comma-separated list:

ENABLED_MODULES=teams,admin-panel

The JavaScript layer

In packages/config/modules.ts, isModuleEnabled(moduleId) reads NEXT_PUBLIC_ENABLED_MODULES at runtime. This means the client knows the module state too, which lets the sidebar render the correct navigation items.

Server components can gate content directly:

import { isModuleEnabled } from '@repo/config/modules'

if (!isModuleEnabled('teams')) {
  return <p>Teams is not enabled for your plan.</p>
}

The .NET layer

The IModule interface marks each feature module. ENABLED_MODULES is read at startup and each module's endpoints are only registered if it's in the list. This means disabled modules add zero overhead - their routes simply don't exist.

Adding your own module

  1. Add the module ID to packages/config/modules.ts
  2. Create a .NET module class implementing IModule
  3. Add the <ModuleGate> wrapper to any UI that should be hidden when disabled
  4. Set ENABLED_MODULES in your environment

That's it. No feature flags service required.