Config Management
Source: Dev.to
Introduction
In a multi‑tenant system—such as a SaaS platform or a chatbot used by multiple companies—it is extremely important to design a robust configuration system.
This article focuses on designing a feature‑flag system on the frontend, based on learnings from building a video‑calling chatbot for websites where each customer needed its own set of features and UI customizations.
Assumptions
- The backend provides tenant‑specific configuration. Designing or implementing the backend is out of scope.
- Configuration values may be edited from multiple places. Handling conflicts and reconciliation is out of scope.
High‑Level Overview
We’ll create a Config Manager that follows a simple two‑phase lifecycle:
- Bootstrap phase – runs once at application start‑up.
- Runtime phase – provides read‑only access to the merged configuration.
Components
ConfigReconciler
- Takes the default configuration and the tenant‑specific configuration.
- Uses a deep‑merge strategy to produce the final configuration.
- Avoids unnecessary deep nesting in the config structure.
ConfigSingleton
- Stores the final configuration in a singleton.
- Allows any part of the app to safely read the configuration without re‑computing it.
Integration
Integrate the bootstrap phase at the application entry point (e.g., main.tsx in a Vite project). The goal is to reconcile configs once during startup and avoid rerunning the deep‑merge logic on every render.
// main.tsx
import { bootstrapConfig } from './configManager';
bootstrapConfig()
.then(() => {
// Render the app after config is ready
ReactDOM.createRoot(document.getElementById('root')!).render(
);
})
.catch(err => {
console.error('Failed to bootstrap config:', err);
});
Usage
After bootstrapping, any component can safely read the configuration via getConfig():
import { getConfig } from './configManager';
function MyButton() {
const config = getConfig();
if (config.buttonEnabled) {
return Click Here;
}
return null;
}
Conclusion
A minimal, two‑phase Config Manager with a deep‑merge reconciler and a singleton store provides a scalable way to handle feature flags in multi‑tenant frontends.
Happy building!