Adaptive Presentation Core (APC)

- Published on
Chapter 5 - Composable Execution Layer (CEL)
Summary
The Composable Execution Layer (CEL) is arguably one of the most transformative developments in the modern frontend stack. It introduces a new mental model for application logic—treating behavior not as embedded script or centralized control, but as modular, dynamic, runtime-executed capability. CEL empowers teams to inject intelligence, automate state, orchestrate effects, and bind services to interface modules without resorting to hardcoded coupling or over-abstracted boilerplate.
From my early experience working on federated UI systems and runtime-driven apps, I saw that frontend architecture needed something more than visual composition. Layout could be decoupled, design systems could be unified, but logic was still sticky—it couldn’t travel with the module. The answer wasn’t just better separation of concerns. It was a new layer. A way to bind, observe, and delegate behavior.
The Composable Execution Layer is that layer. It coordinates the dynamic needs of feature teams: experimentation, observability, service access, context sensitivity, and logic injection. It closes the gap between modular rendering and modular thinking.
As the frontend becomes more platform-like, CEL becomes the operating system for capability orchestration.
Historical Context and Why It Matters
The rise of the Composable Execution Layer (CEL) was not accidental—it was the inevitable response to the limitations of legacy frontend behavior models. In traditional applications, business logic was often centralized in service layers or global stores. State flowed downward from root containers. Contexts proliferated, tightly coupling modules to the app’s internal assumptions.
As a pioneer in composable frontend architecture, I saw firsthand how this rigidity became a bottleneck. Teams couldn’t experiment freely. Features became hard to test in isolation. Cross-cutting concerns like analytics or authorization became deeply embedded in core views, leading to regression risk with every change.
I realized that layout composition (via DIM) wasn’t enough. We also needed a runtime logic mesh—a way to declare, inject, and coordinate behavior that respected module boundaries. CEL was born from that need: a behavioral abstraction layer for frontends that think like platforms.
CEL challenges old assumptions:
- That behavior must live in global stores or context providers.
- That logic is tightly coupled to components.
- That events, services, and state must be wired manually by app integrators.
Instead, CEL proposes a world where:
- Modules declare what they need (data, events, observers).
- The runtime provides it based on context.
- Cross-cutting services can plug in without rewriting core logic.
CEL turns feature logic into portable units—units that can be shipped independently, replaced cleanly, and orchestrated dynamically.
Patterns and Anti-Patterns in CEL
Implementing CEL correctly requires a shift in how teams think about frontend logic—not as application scaffolding, but as dynamic capability orchestration. Done right, CEL enables autonomy, testability, and clean separation of concerns. Done poorly, it becomes a brittle layer of indirection. Here's what to aim for—and what to avoid.
✅ Recommended Patterns
Declarative Execution Contracts
Modules declare the behavior they require—data sources, observers, event handlers—rather than wiring logic imperatively.Context-Scoped Services
Services (e.g., analytics, auth, feature flags) are injected based on the current execution context (user, tenant, brand, A/B test).Lazy-Orchestrated Side Effects
Side effects like API calls, logging, or DOM updates are registered declaratively and invoked via lifecycle hooks or event triggers—not run on component mount.Separation of Side Effects and State
State is derived from clean sources (e.g., props, stores, or async hooks). Side effects are isolated into dedicated handlers or services.Compositional Middleware
Logic enhancements (e.g., caching, retry, debounce) are composed via middleware or plugin stacks—not embedded in module code.
🚫 Anti-Patterns to Avoid
Global Store Dependency
Relying on shared global state (Redux, MobX, Context) tightly couples modules and breaks portability.Behavior in Layout
Avoid embedding execution logic inside layout shells. Layouts should orchestrate structure, not behavior.Event Coupling Between Modules
Don’t wire one module’s event directly to another. Use publish/subscribe models or CEL event routers to maintain decoupling.Over-abstracted Providers
Nesting dozens of context providers to simulate behavior configuration leads to poor DX and brittle APIs. Prefer service registries or scoped hooks.Silent Failures in Side Effects
Failing to track or observe errors in composed logic makes CEL hard to debug. Use telemetry and trace propagation.
Contract Modularity and Runtime Injection
To make CEL scale across organizations and product lines, execution contracts must be modular themselves. This means they support:
- Base + override models (e.g., core logic + tenant extension)
- Schema validation for consistency and upgrade safety
- Composable services via named registries, plugin chains, or observables
Example: Composing Contracts
// base contract
export const baseContract = {
requires: ['auth', 'analytics'],
context: ['user', 'region']
};
// extended contract for premium tenants
export const extendedContract = {
...baseContract,
requires: [...baseContract.requires, 'advancedFeature'],
context: [...baseContract.context, 'plan']
};
CEL uses a dependency injection container pattern under the hood:
- Modules declare needs
- The container resolves implementations from a scoped registry
- Context variables filter which services apply
Runtime Service Injection
CEL.register('spend-dashboard', extendedContract, ({ context, services }) => {
const authz = services.auth.check(context.user);
if (context.plan === 'premium') {
services.advancedFeature.activate();
}
services.analytics.log('SpendDashboardMounted');
});
If services are unavailable or contracts are misdeclared, CEL logs telemetry and gracefully skips non-critical actions.
Real-World Use Cases and Implementation Examples
In practice, CEL often emerges through a blend of framework conventions and platform-specific innovations. Here are several real-world patterns and use cases that demonstrate how teams are adopting CEL across different industries and frontend stacks:
📦 Pattern: Declarative Side Effects per Slot
- Use Case: A retail platform uses a runtime manifest to define which modules occupy which layout slots.
- Execution Layer: Each module exposes a
useExecution()
oruseEffect()
hook that binds analytics, feature flags, and data queries declaratively, scoped to the module's mount lifecycle.
function OrdersSummaryModule() {
const { analytics, flags, fetcher } = useExecution(['analytics', 'featureFlags', 'dataService']);
useEffect(() => {
if (flags['track_orders']) {
analytics.log('OrdersModuleMounted');
}
fetcher.load('/api/orders/summary');
}, []);
return <OrdersSummaryTable />;
}
Result: Teams deliver telemetry and experimentation logic without modifying the page shell or adding more context providers. Each module brings its logic with it, clearly defined and encapsulated.
Use Case: A retail platform uses a runtime manifest to define which modules occupy which layout slots.
Execution Layer: Each module exposes a
useExecution()
hook that binds analytics, feature flags, and data queries declaratively, scoped to the module's mount lifecycle.Result: Teams deliver telemetry and experimentation logic without modifying the page shell or adding more providers.
🪄 Pattern: Plugin-Based Behavior Injection
- Use Case: A fintech dashboard registers auth, currency formatting, and role-based UI logic through a plugin interface defined in CEL.
- Execution Layer: The app shell loads these plugins based on the tenant, then exposes scoped runtime services via dependency injection. Plugins are discovered by scanning the manifest at runtime or using a registry keyed by
tenantId
. Once resolved, they are attached to a CEL context container scoped to the module lifecycle.
// registry plugin map
const pluginRegistry = {
'tenant-alpha': [authPlugin, currencyPlugin],
'tenant-beta': [authPlugin, advancedFormatter]
};
function loadPluginsForTenant(tenantId) {
return pluginRegistry[tenantId] || [];
}
// execution
CEL.register('finance-summary', contract, ({ context, services }) => {
const plugins = loadPluginsForTenant(context.tenantId);
plugins.forEach(plugin => plugin.attach(services));
services.logger.log('FinanceModuleReady');
});
Result: New business logic can be added or swapped by updating the registry, without altering the base app or duplicating logic per region.
Use Case: A fintech dashboard registers auth, currency formatting, and role-based UI logic through a plugin interface defined in CEL.
Execution Layer: The app shell loads these plugins based on the tenant, then exposes scoped runtime services via dependency injection.
Result: New business logic can be added without altering the base app or duplicating logic per region.
🧩 Pattern: Contextual Data Fetching
- Use Case: A B2B SaaS application loads user-specific settings, permissions, and labels using CEL’s composition runtime.
- Execution Layer: Module logic uses declarative loaders that receive route context, feature flags, and browser locale.
// sample execution contract
export const userContextContract = {
requires: ['userSettingsService'],
context: ['locale', 'featureFlags', 'userId']
};
CEL.register('user-preferences', userContextContract, ({ context, services }) => {
const { locale, featureFlags, userId } = context;
services.userSettingsService.loadPreferences(userId, locale, featureFlags);
});
Result: Frontend apps adapt dynamically to user context without baking context resolution into each component.
Use Case: A B2B SaaS application loads user-specific settings, permissions, and labels using CEL’s composition runtime.
Execution Layer: Module logic uses declarative loaders that receive route context, feature flags, and browser locale.
Result: Frontend apps adapt dynamically to user context without baking context resolution into each component.
🧪 Pattern: Testable Behavioral Contracts
- Use Case: A media company wraps all feature logic in behavior units that define what should happen on click, hover, idle, or load.
- Execution Layer: CEL interprets these declaratively and emits logs/test artifacts for synthetic and e2e validation.
// Behavioral contract
export const executionUnit = {
onClick: [trackClick, notifyHandler],
onIdle: [recordIdleTime]
};
// Testing the execution
describe('executionUnit', () => {
it('should fire click and idle events in sequence', () => {
const effects = traceEffects(executionUnit);
effects.onClick();
effects.onIdle();
expect(effects.trace).toEqual([
'trackClick',
'notifyHandler',
'recordIdleTime'
]);
});
});
Result: Feature logic becomes observable and testable independently of the UI, enabling developers to validate behavior in isolation without needing to render full interface modules or mock global application state.
Use Case: A media company wraps all feature logic in behavior units that define what should happen on click, hover, idle, or load.
Execution Layer: CEL interprets these declaratively and emits logs/test artifacts for synthetic and e2e validation.
Result: Feature logic becomes observable and testable independently of the UI. through a blend of framework conventions and platform-specific innovations. Here are several real-world patterns and use cases that demonstrate how teams are adopting CEL across different industries and frontend stacks:
📦 Pattern: Declarative Side Effects per Slot
- Use Case: A retail platform uses a runtime manifest to define which modules occupy which layout slots.
- Execution Layer: Each module exposes a
useExecution()
hook that binds analytics, feature flags, and data queries declaratively, scoped to the module's mount lifecycle. - Result: Teams deliver telemetry and experimentation logic without modifying the page shell or adding more providers..
Let’s explore how CEL shows up in real applications—specifically in modular product suites where behavioral logic varies by module, user role, or deployment context.
📦 Example 1: Modular Accounting Platform
In a composable accounting suite with modules for AP, AR, and Spend, CEL coordinates behavior across modules that handle:
- API data fetching
- Authorization gates
- Telemetry
- Feature flag conditions
Module contract (AR Dashboard)
export const executionContract = {
requires: ['customerApi', 'auth', 'tracking'],
events: ['onMount', 'onError'],
context: ['tenantId', 'userRole']
};
Injected behavior (CEL runtime)
CEL.register('ar-dashboard', executionContract, ({ context, services }) => {
services.auth.checkPermission(context.userRole);
services.tracking.log('AR loaded', { tenantId: context.tenantId });
services.customerApi.fetchOutstanding();
});
Each module defines its needs declaratively. CEL resolves them based on runtime context, ensuring:
- Tenant-based auth policies are enforced
- Data access and logging are scoped per user
- Modules are testable in isolation
🧩 Example 2: Feature Flag-Driven UI
In a customer support dashboard, CEL handles logic toggles:
CEL.when('feature:conversationTags').run(() => {
render(<ConversationTagManager />);
});
CEL.whenNot('feature:conversationTags').run(() => {
render(<LegacyTagEditor />);
});
This keeps flag logic out of views and maintains modular rendering.
🧪 Example 3: Testable Side Effect Units
A media player component declares its behavioral side effects for CEL to handle:
export const executionUnit = {
onPlay: [logPlayEvent, maybeStartPromoTracking],
onPause: [logPauseEvent],
onComplete: [fireEngagementPixel]
};
CEL binds events from the UI and executes handlers, logging each as telemetry and handling fallbacks automatically.
Observability and Metrics
CEL becomes foundational infrastructure in composable frontends—and like any infrastructure, it must be observable and measurable. Because CEL executes runtime behavior, the failure to track its decisions and side effects leads to blind spots in how the system behaves.
🔍 Key Observability Strategies
- Execution lifecycle events – emit
onInit
,onReady
,onFailure
hooks per module - Contract tracing – log which declared requirements were matched, injected, or failed
- Context propagation tracing – monitor how user, theme, or tenant context flows through service handlers
- Side effect audit trail – every CEL action (e.g., data fetch, log emit) is recorded and time-stamped for diagnostics
📏 Metrics to Track
- Behavior Resolution Time (ms) – how long from module load to behavior execution
- Contract Satisfaction Rate (%) – percentage of modules whose declared contracts were successfully fulfilled
- Behavior Reuse Ratio – how many modules share the same behavioral service (indicates successful modularization)
- Failed Execution Attempts – how often service injection fails or logic crashes due to context issues
- Shadow Execution Mode – ability to simulate execution without performing real side effects (for preview/test)
📊 Visual Instrumentation
Consider dashboards or overlays that show:
- Active services injected into each slot
- Real-time events emitted by modules
- Behavioral traces tied to module origin, version, or tenant
CEL without observability is a black box. CEL with observability becomes a runtime map of how your frontend thinks.
Diagram: The Role of CEL in the Composable Stack
+--------------------------+
| Layout Shell (DIM) |
| - Slots: header, main |
| - Manifest resolution |
+--------------------------+
↓
+--------------------------+
| Module (e.g. Dashboard) |
| - UI code |
| - executionContract |
+--------------------------+
↓
+--------------------------+
| CEL Runtime |
| - Resolve services |
| - Inject context |
| - Attach observers |
| - Track execution |
+--------------------------+
This diagram illustrates how CEL operates between the layout (DIM) and module execution layers. Modules define what logic they need, and CEL orchestrates that logic in real time, scoped to user, tenant, or session.
Lifecycle and Multi-Team Execution Scope
To scale CEL in large organizations, behavior execution must be lifecycle-aware and team-safe. This means:
- Execution is scoped to slot lifecycle (mount, update, unmount)
- Services are sandboxed to the module that declared them
- Cross-module side effects are monitored and rate-limited
Execution Lifecycle Hooks
CEL.register('ar-dashboard', contract, ({ context, services }) => ({
onInit: () => services.logger.log('init'),
onReady: () => services.analytics.fire('ready'),
onDispose: () => services.logger.log('cleanup')
}));
This ensures:
- No service runs unless context is satisfied
- Mount/unmount cleanup is enforced
- Execution is idempotent across navigation changes
Team Collaboration and Governance
To support 10+ frontend teams:
- CEL provides local mocks and test runners for contract validation
- CI checks validate executionContract schema alignment with platform registry
- Feature teams document their contracts via auto-generated dashboards
CEL becomes a governance framework—blending autonomy with runtime guarantees.
Testability and Developer Tooling
As CEL governs runtime behavior across modules, its integration must be testable. Developers need confidence in how contracts resolve, how side effects behave, and how logic can be verified without full-system integration.
🔬 Test Strategies
- Contract Schema Testing – Validate declared contracts using JSON Schema or TypeScript types
- Local CEL Mocks – Mock CEL behavior registry per module to simulate resolution
- Effect Trace Inspection – Inspect and assert which behaviors were called, in what order, and with what parameters
- Service Injection Testing – Validate fallback behavior when service is missing, misconfigured, or version-skewed
🔧 Tooling Patterns
createMockContractRunner(contract, overrides)
– simulate CEL runtimetraceEffects(handler)
– wrap a logic handler and log all execution pathsassertTelemetry(expectedEvents)
– confirm behavior triggers telemetry hooks
CEL and Server-Side Rendering (SSR)
CEL is primarily designed for runtime behavior, but in SSR-first architectures, it must integrate without breaking hydration, replay consistency, or server logs.
SSR Compatibility Principles
- Defer Side Effects – Allow CEL to register behaviors but defer invocation until client hydration completes
- Serialize Context – Capture context (e.g. locale, tenant, flags) server-side and hydrate it into CEL on the client
- Client-Only Handlers – Mark some behaviors (like DOM effects or browser APIs) as client-only
- Telemetry Staging – Buffer analytics calls until client context is resolved and dispatch conditions are met
SSR Hook Example
CEL.register('summary-box', contract, ({ services }) => ({
onReady: () => {
if (typeof window !== 'undefined') {
services.analytics.fire('SummaryLoaded');
}
}
}));
CEL in SSR-mode doesn’t execute—it prepares.
Done right, CEL gives server-rendered apps the same dynamic orchestration advantages as client-side ones—without compromising performance or consistency.
What Comes Next
With CEL in place, logic becomes portable, observable, and declarative. Teams gain the ability to bind services, observe behavior, and decouple execution from layout. In the next chapter, we move up the stack to the Adaptive Presentation Core (APC)—where visual behavior, themes, and responsive design take modular rendering to the next level.