Skip to main content
Helios is built on a fundamentally different architecture than traditional programmatic video frameworks. Instead of simulating animation in JavaScript, Helios drives the browser’s native animation engine.

Core philosophy: native-aligned architecture

Most programmatic video frameworks treat the browser as a “screenshot machine”—they freeze time, inject frame numbers, calculate every interpolated value in JavaScript, and capture the result. This simulation-based architecture works, but it means reimplementing what the browser already does natively. Helios takes a different approach: drive the browser’s animation engine, don’t replace it.

The browser already knows how to animate

When you write CSS animations or use the Web Animations API, the browser’s C++ rendering engine handles:
  • Interpolation calculations
  • Easing functions
  • Hardware-accelerated compositing
  • Subpixel rendering
  • Performance optimizations
Helios leverages these native capabilities by controlling time rather than values.
/* Standard CSS - no changes needed */
@keyframes fadeIn {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: scale(1); }
}

.element {
  animation: fadeIn 1s ease-out forwards;
}
// Helios controls time, browser handles animation
helios.seek(45);
// All CSS/WAAPI animations instantly update to frame 45

Dual-mode time control

Helios uses different time control mechanisms depending on the context:

Production rendering: CDP virtual time

For server-side rendering in headless Chrome, Helios uses the Chrome DevTools Protocol (CDP) to virtualize time at the environment level.
// Simplified internal flow
await cdp.send('Emulation.setVirtualTimePolicy', {
  policy: 'advance',
  budget: 33.33  // Advance by exactly one frame (33.33ms at 30fps)
});
Key characteristics:
  • Deterministic: The browser cannot advance until the frame is fully rendered
  • Scene-independent: Render time is proportional to scene complexity
  • Native: All CSS animations, WAAPI timelines, and requestAnimationFrame callbacks update automatically
  • Chromium-only: Requires CDP access (headless Chrome/Chromium)
See packages/renderer/src/drivers/CdpTimeDriver.ts:20 for implementation details.

Preview mode: WAAPI seeking

For browser-based preview and development, Helios uses the Web Animations API to seek individual animations.
// Seek all animations to target time
document.getAnimations().forEach(anim => {
  anim.currentTime = targetTimeMs;
  anim.pause();
});
Key characteristics:
  • Interactive: Works in any modern browser
  • Real-time: No headless browser required
  • Standards-based: Uses the writable Animation.currentTime property
  • Scrub-friendly: Perfect for timeline scrubbing in the player
See packages/core/src/drivers/DomDriver.ts:372 for implementation details.
The W3C spec marks document.timeline.currentTime as read-only, but individual Animation objects expose a writable .currentTime property. Helios uses this to seek animations without violating the spec.

Modular architecture

Helios is designed as a set of loosely-coupled packages:

Core (@helios-project/core)

Headless logic engine with zero UI dependencies. Responsibilities:
  • Timeline state management (currentFrame, duration, fps)
  • Playback controls (play, pause, seek)
  • Signal-based reactivity
  • Driver abstraction (TimeDriver, DomDriver, NoopDriver)
  • Animation helpers (interpolate, spring, sequence)
Key files:
  • Helios.ts:79 - Main engine class
  • types.ts:11 - Configuration and state types
  • drivers/ - Driver implementations

Renderer (@helios-project/renderer)

Server-side rendering pipeline using Playwright and FFmpeg. Responsibilities:
  • CDP-based time control
  • Frame capture (screenshots or canvas)
  • Video encoding pipeline
  • Distributed rendering orchestration
Key files:
  • Renderer.ts - Main rendering coordinator
  • drivers/CdpTimeDriver.ts:6 - Virtual time driver
  • strategies/CanvasStrategy.ts - Canvas-to-video path

Player (@helios-project/player)

Web Component for browser-based preview. Responsibilities:
  • Sandboxed iframe rendering
  • Transport controls UI
  • Timeline scrubbing
  • Client-side export (WebCodecs)

Studio (@helios-project/studio)

Visual composition editor (currently in beta). Responsibilities:
  • Visual timeline editing
  • Asset management
  • Real-time preview
  • Export workflows

Framework-agnostic design

The core engine is a vanilla TypeScript class with zero framework dependencies. Framework adapters provide idiomatic APIs:
import { useVideoFrame } from '@helios-project/react';

function MyComponent() {
  const { currentFrame, currentTime } = useVideoFrame();
  return <div>Frame: {currentFrame}</div>;
}

Signal-based reactivity

Helios uses a custom signal implementation for fine-grained reactivity:
// Internal implementation (simplified)
class Helios {
  private _currentFrame: Signal<number>;
  private _currentTime: ReadonlySignal<number>;

  constructor(options) {
    this._currentFrame = signal(0);
    this._currentTime = computed(() => 
      this._currentFrame.value / this._fps.value
    );
  }

  seek(frame: number) {
    this._currentFrame.value = frame; // Triggers subscribers
  }
}
This enables:
  • Efficient updates: Only changed values trigger re-renders
  • Computed values: Derived state updates automatically
  • Framework adapters: Easy integration with React, Vue, etc.
See packages/core/src/signals.ts for the full implementation.

Stability and determinism

Deterministic rendering requires waiting for all asynchronous operations to complete before capturing each frame.

Stability checks

Helios waits for:
  1. Fonts: document.fonts.ready
  2. Images: img.decode() for all images
  3. Media elements: seeked event after seeking video/audio
  4. Custom checks: User-registered async operations
await helios.waitUntilStable();
This method is called automatically during rendering, but you can also use it for deterministic testing.

Custom stability checks

Register custom async operations that should block rendering:
helios.registerStabilityCheck(async () => {
  // Wait for Three.js scene to finish loading
  await scene.loadAssets();
});
See Helios.ts:876 for the stability check API.

Advantages of this architecture

Performance

  • Hardware acceleration: Browser’s C++ compositor handles all interpolation
  • Optimized rendering: Same engine that powers the web
  • Zero JavaScript overhead: No per-frame calculation loops

Maintainability

  • Declarative CSS: Animation logic lives in stylesheets, not code
  • Separation of concerns: Styling vs. logic
  • Less code: Browser does the heavy lifting

Familiarity

  • Standard web APIs: CSS @keyframes, WAAPI, requestAnimationFrame
  • Transferable skills: Existing web development knowledge applies
  • Library compatibility: Works with GSAP, Framer Motion, Motion One, etc.
This architecture is a bet on native platform capabilities. If you need maximum compatibility or control over every interpolated value, simulation-based approaches like Remotion may be more appropriate.

Trade-offs and constraints

Browser dependency

Helios requires Chromium for production rendering (CDP access). This is a harder dependency than simulation-based approaches that can run in any JavaScript environment.

Time control limitations

CDP virtual time is powerful but Chromium-specific. Other browsers don’t expose equivalent APIs (yet).

Learning curve for advanced use cases

While basic CSS animations “just work,” advanced scenarios (canvas rendering, complex synchronization) may require understanding Helios’s driver system.

Next steps

Build docs developers (and LLMs) love