> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heliosrender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create your first programmatic video with Helios in minutes. A hands-on tutorial from setup to render.

# Quickstart

This guide will walk you through creating your first Helios composition from scratch. In about 10 minutes, you'll have a working animated video.

> [!NOTE]
>
> We'll build a simple canvas animation that you can preview in your browser and render to MP4. This example uses vanilla JavaScript, but Helios works with React, Vue, Svelte, and other frameworks.

## What we're building

A 5-second animation featuring:

* A circle moving across the screen
* A rotating square in the center
* Smooth, frame-perfect playback

## Setup your project

**1. Create a new project directory**

```bash theme={null}
mkdir my-first-helios-video
cd my-first-helios-video
npm init -y
```

**2. Install dependencies**

```bash theme={null}
npm install @helios-project/core @helios-project/player vite
```

This installs:

* `@helios-project/core` - The animation engine
* `@helios-project/player` - Preview player
* `vite` - Development server and bundler

**3. Create project files**

Create the following file structure:

```
my-first-helios-video/
├── package.json
├── index.html
└── src/
    └── main.ts
```

## Create your composition

### HTML entry point

Create **index.html**:

```html theme={null}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My First Helios Video</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        width: 100vw;
        height: 100vh;
        overflow: hidden;
        background: #000;
      }
      #composition-canvas {
        display: block;
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <canvas id="composition-canvas"></canvas>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
```

### Composition logic

Create **src/main.ts**:

```typescript theme={null}
import { Helios, HeliosState } from '@helios-project/core';

const canvas = document.getElementById('composition-canvas') as HTMLCanvasElement;
const ctx = canvas.getContext('2d')!;

// Setup canvas to match window size
const resizeCanvas = () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
};

resizeCanvas();
window.addEventListener('resize', resizeCanvas);

// Video configuration
const duration = 5; // seconds
const fps = 30;

// Initialize Helios engine
const helios = new Helios({
  duration,
  fps,
});

// Bind to document timeline so the player can drive us
helios.bindToDocumentTimeline();

// Draw function - called on every frame update
function draw(currentFrame: number) {
  const time = currentFrame / fps * 1000; // Convert to milliseconds
  const progress = (time % (duration * 1000)) / (duration * 1000); // 0 to 1

  const { width, height } = canvas;

  // Clear canvas
  ctx.fillStyle = '#111';
  ctx.fillRect(0, 0, width, height);

  // Draw moving circle
  const x = progress * width;
  const y = height / 2;
  const radius = 50;

  ctx.fillStyle = 'royalblue';
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  ctx.fill();

  // Draw rotating square
  const squareSize = 100;
  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.rotate(progress * Math.PI * 2);
  ctx.fillStyle = 'tomato';
  ctx.fillRect(-squareSize / 2, -squareSize / 2, squareSize, squareSize);
  ctx.restore();
}

// Subscribe to Helios state changes
helios.subscribe((state: HeliosState) => {
  draw(state.currentFrame);
});

// Expose helios globally for debugging and player control
declare global {
  interface Window {
    helios: Helios;
  }
}
window.helios = helios;
```

### Understanding the code

Let's break down what's happening:

**1. Initialize Helios**

```typescript theme={null}
const helios = new Helios({
  duration: 5,  // 5 second video
  fps: 30,      // 30 frames per second = 150 total frames
});
```

This creates a Helios instance that manages the animation timeline.

**2. Bind to document timeline**

```typescript theme={null}
helios.bindToDocumentTimeline();
```

This connects Helios to the browser's native animation system, allowing the player and renderer to control playback.

**3. Subscribe to frame updates**

```typescript theme={null}
helios.subscribe((state: HeliosState) => {
  draw(state.currentFrame);
});
```

Every time Helios updates (play, pause, seek), your draw function is called with the current frame number.

**4. Calculate progress**

```typescript theme={null}
const progress = (time % (duration * 1000)) / (duration * 1000);
```

Convert the current frame to a 0-1 progress value. This makes it easy to animate properties smoothly.

**5. Expose to window**

```typescript theme={null}
window.helios = helios;
```

The player and renderer look for `window.helios` to control your composition.

## Preview your composition

**1. Add dev script to package.json**

```json theme={null}
{
  "scripts": {
    "dev": "vite"
  }
}
```

**2. Start the dev server**

```bash theme={null}
npm run dev
```

Open your browser to `http://localhost:5173`. You should see your animation!

**3. Test the preview controls**

Open your browser console and try:

```javascript theme={null}
// Play the animation
helios.play();

// Pause
helios.pause();

// Jump to frame 75 (middle of the video)
helios.seek(75);

// Get current state
console.log(helios.getState());
```

## Add the player component

For a better preview experience with UI controls, use the Helios Player:

**1. Create a player HTML file**

Create **preview\.html**:

```html theme={null}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Helios Player Preview</title>
  </head>
  <body>
    <helios-player 
      src="./index.html" 
      width="1920" 
      height="1080"
    ></helios-player>
    
    <script type="module">
      import '@helios-project/player';
    </script>
  </body>
</html>
```

**2. Preview with player controls**

Navigate to `http://localhost:5173/preview.html`

You now have:

* Play/pause button
* Seek bar
* Frame counter
* Export options

> [!NOTE]
>
> The player loads your composition in a sandboxed iframe, providing isolation and standard HTMLMediaElement controls.

## Render to video

Now let's render your composition to an MP4 file.

**1. Install the renderer**

```bash theme={null}
npm install @helios-project/renderer
```

**2. Create a render script**

Create **render.ts**:

```typescript theme={null}
import { Renderer } from '@helios-project/renderer';
import { resolve } from 'path';

const renderer = new Renderer({
  width: 1920,
  height: 1080,
  fps: 30,
  mode: 'canvas', // Use canvas rendering strategy
});

const compositionUrl = `file://${resolve('./dist/index.html')}`;
const outputPath = './output.mp4';

console.log('Starting render...');

await renderer.render(compositionUrl, outputPath);

console.log(`Video saved to ${outputPath}`);
```

**3. Update package.json scripts**

```json theme={null}
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "render": "npm run build && npx tsx render.ts"
  }
}
```

**4. Install tsx for running TypeScript**

```bash theme={null}
npm install -D tsx
```

**5. Render your video**

```bash theme={null}
npm run render
```

This will:

1. Build your composition with Vite
2. Launch headless Chrome
3. Capture each frame
4. Encode to MP4 with FFmpeg

Your video will be saved as `output.mp4`!

> [!WARNING]
>
> Make sure your composition is built before rendering. The renderer needs the bundled files, not source files.

## Using animation helpers

Helios includes powerful animation utilities. Let's enhance our composition:

```typescript theme={null}
import { Helios, interpolate, spring } from '@helios-project/core';

helios.subscribe((state: HeliosState) => {
  const { currentFrame } = state;
  
  // Smooth easing with interpolate
  const x = interpolate(
    currentFrame,
    [0, 150],           // Input range (frames)
    [0, canvas.width],  // Output range (pixels)
    { easing: (t) => t * t * (3 - 2 * t) } // Smoothstep easing
  );
  
  // Spring physics for bounce
  const scale = spring({
    frame: currentFrame,
    fps: 30,
    from: 1,
    to: 2,
    config: { tension: 300, friction: 10 }
  });
  
  // Draw with animated values
  ctx.save();
  ctx.translate(x, canvas.height / 2);
  ctx.scale(scale, scale);
  
  ctx.fillStyle = 'royalblue';
  ctx.beginPath();
  ctx.arc(0, 0, 50, 0, Math.PI * 2);
  ctx.fill();
  
  ctx.restore();
});
```

### Available helpers

```typescript interpolate theme={null}
import { interpolate } from '@helios-project/core';

// Linear interpolation
const opacity = interpolate(
  currentFrame,
  [0, 30],    // Frames 0-30
  [0, 1],     // Opacity 0-100%
);

// With easing
const x = interpolate(
  currentFrame,
  [0, 150],
  [0, 1920],
  { easing: (t) => Math.pow(t, 2) } // Ease in quad
);

// Clamp extrapolation
const scale = interpolate(
  currentFrame,
  [30, 60],
  [1, 2],
  { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
```

```typescript spring theme={null}
import { spring } from '@helios-project/core';

// Physics-based animation
const y = spring({
  frame: currentFrame,
  fps: 30,
  from: 0,
  to: 100,
  config: {
    tension: 300,  // Spring stiffness
    friction: 10,  // Damping
  }
});
```

```typescript easing theme={null}
import { easings } from '@helios-project/core';

// Predefined easing functions
const t = currentFrame / 150;
const eased = easings.easeInOutCubic(t);

// Available: linear, easeInQuad, easeOutQuad, easeInOutQuad,
// easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart,
// easeOutQuart, easeInOutQuart, easeInExpo, easeOutExpo,
// easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc,
// easeInBack, easeOutBack, easeInOutBack, easeInElastic,
// easeOutElastic, easeInOutElastic, easeInBounce,
// easeOutBounce, easeInOutBounce
```

## Next steps

> [card] Explore examples
>
> Check out 80+ examples in the [GitHub repository](https://github.com/BintzGavin/helios/tree/main/examples) covering:
>
> * GSAP animations
> * Three.js 3D scenes
> * Chart.js visualizations
> * Lottie animations
> * Framer Motion
> * And more

> [card] Learn the API
>
> Dive deeper into Helios capabilities:
>
> * Audio tracks and mixing
> * Captions and subtitles
> * Input props and schemas
> * Timeline markers
> * Distributed rendering

> [card] Framework integration
>
> Use Helios with your preferred framework:
>
> * React with `useVideoFrame()` hook
> * Vue with composables
> * Svelte with stores
> * Solid.js integration

> [card] Production rendering
>
> Deploy Helios for scale:
>
> * Docker containerization
> * AWS Lambda distributed rendering
> * Google Cloud Run
> * Local orchestrator for parallel rendering

## Troubleshooting

### Canvas is blank

Make sure you:

1. Resize the canvas to match the window
2. Clear the canvas before drawing
3. Subscribe to Helios state updates

### Animation doesn't update

Verify that:

1. `helios.bindToDocumentTimeline()` is called
2. `window.helios` is exposed
3. You're calling `helios.play()` or seeking manually

### Render produces black frames

Check that:

1. Your composition is built (`npm run build`)
2. The composition URL is correct (use `file://` protocol)
3. The canvas has proper dimensions

### TypeScript errors

Add type declarations:

```typescript theme={null}
declare global {
  interface Window {
    helios: Helios;
  }
}
```

## Tips for success

**1. Start simple**

Begin with basic shapes and movements. Add complexity gradually.

**2. Use progress values**

Convert frames to 0-1 progress for easier math:

```typescript theme={null}
const progress = currentFrame / (duration * fps);
```

**3. Preview often**

The dev server provides instant feedback. Use it liberally.

**4. Expose to window**

Always export `window.helios` so the player and renderer can control your composition.

**5. Test different frame rates**

30fps is standard, but try 60fps for smoother motion or 24fps for a cinematic feel.

> [!NOTE]
>
> Congratulations! You've created your first Helios video. The same patterns you learned here scale to complex, production-ready compositions.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.