packages/@n8n/expression-runtime/docs/implementation-phases.md
This document maps interfaces to implementation phases to help developers focus on what's needed when.
Goal: Basic expression evaluation working in CLI/backend
Interfaces Needed:
RuntimeBridge - Main bridge interfaceBridgeConfig (without debug field)RuntimeHostInterface - Runtime-to-host communicationRuntimeGlobals - Globals injected into runtimeWorkflowDataProxy - Data access helperIExpressionEvaluator - Public APIEvaluatorConfig (without observability)WorkflowData - Input data formatEvaluateOptions (basic)Implementations Required:
IsolatedVmBridge - For CLI/backendExpressionEvaluator - Main evaluator classCan Skip:
NoOpProvider stub)Error)Goal: Add metrics, traces, and logs
Interfaces Needed:
ObservabilityProviderMetricsAPITracesAPILogsAPISpanImplementations Required:
NoOpProvider (zero overhead when disabled)OpenTelemetryProviderPostHogProvider (optional)CompositeProvider (use multiple providers)Integration:
EvaluatorConfig.observabilityGoal: Handle concurrent evaluations
New Interfaces: None (uses existing RuntimeBridge)
Implementations Required:
IsolatePool classGoal: 100% test compatibility
New Interfaces: None
Implementation: Extension functions in runtime
Goal: Graceful error handling with clear messages
Interfaces Needed:
ExpressionErrorMemoryLimitErrorTimeoutErrorSecurityViolationErrorSyntaxErrorImplementation: Error handling in all code paths
Interfaces: Already defined (same RuntimeBridge)
Implementations:
WebWorkerBridgeConfig: BridgeConfig.debug field
Implementation:
Task runners already have process-level isolation. Expression evaluation happens inside the task runner (no IPC to worker needed).
Option A: Use IsolatedVmBridge locally within task runner
Option B: Evaluate directly without extra sandbox
Decision pending - will be made during Phase 2+ implementation.
Phase 1: Skip - Web Workers are Phase 2+
Phase 2: Focus on:
RuntimeBridge interface - Your bridge must implement thisBridgeConfig - Configuration optionsWorkflowDataProxy - How to structure dataKey Difference: Web Workers can't do lazy loading initially, so you'll need to pre-fetch all data before calling execute().
Phase 1.1: Focus on:
IsolatedVmBridge implementationExpressionEvaluator classUse: NoOpProvider for observability initially
Phase 0.2: Add real observability providers
Integration tests use IsolatedVmBridge directly (see src/__tests__/integration.test.ts).
All interfaces in src/types/ are stable enough to write against before the
bridge implementation lands.