Skip to main content

ADR-001: Config-Driven UI Architecture

Status

Accepted

Context

We need to build a multi-tenant vertical application platform where:

  1. Different customers (tenants) need customized UI layouts and branding
  2. Business users should be able to modify UI without code deployments
  3. Development teams need rapid prototyping capabilities
  4. The system must be type-safe and maintainable

Traditional approaches include:

  • Hardcoded layouts: Simple but requires code changes for customization
  • CMS-driven: Flexible but lacks type safety and developer experience
  • Feature flags: Good for toggles but not for layout composition

Decision

We will implement a config-driven UI architecture where:

  1. TypeScript configuration files define tenant layouts
  2. Components are registered in a ComponentRegistry by name
  3. SlotRenderer dynamically renders components based on config
  4. Store bindings automatically inject state as props
  5. Visibility conditions control component rendering
// Example: Config defines what renders, not how
{
component: 'PropertyCard',
priority: 1,
props: { showMap: true },
storeBindings: [
{ prop: 'address', storePath: 'property.selected' }
],
showWhen: (state) => state.stage.current === 'review'
}

Consequences

Positive

  • Type safety: Full TypeScript support in configs
  • Rapid iteration: Change config, see results immediately
  • Multi-tenancy: Each tenant gets isolated configuration
  • Testability: Configs can be unit tested
  • Developer experience: IDE autocomplete and validation

Negative

  • Learning curve: Developers must understand the config system
  • Debugging complexity: Indirection between config and rendered UI
  • Component registry overhead: All components must be registered

Neutral

  • Component constraints: Components must be designed for config-driven use
  • State coupling: Store bindings create implicit dependencies