> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/BintzGavin/helios/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.
</Note>

## 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

<Steps>
  <Step title="Create a new project directory">
    ```bash theme={null}
    mkdir my-first-helios-video
    cd my-first-helios-video
    npm init -y
    ```
  </Step>

  <Step title="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
  </Step>

  <Step title="Create project files">
    Create the following file structure:

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

## 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:

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Expose to window">
    ```typescript theme={null}
    window.helios = helios;
    ```

    The player and renderer look for `window.helios` to control your composition.
  </Step>
</Steps>

## Preview your composition

<Steps>
  <Step title="Add dev script to package.json">
    ```json theme={null}
    {
      "scripts": {
        "dev": "vite"
      }
    }
    ```
  </Step>

  <Step title="Start the dev server">
    ```bash theme={null}
    npm run dev
    ```

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

  <Step title="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());
    ```
  </Step>
</Steps>

## Add the player component

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

<Steps>
  <Step title="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>
    ```
  </Step>

  <Step title="Preview with player controls">
    Navigate to `http://localhost:5173/preview.html`

    You now have:

    * Play/pause button
    * Seek bar
    * Frame counter
    * Export options
  </Step>
</Steps>

<Note>
  The player loads your composition in a sandboxed iframe, providing isolation and standard HTMLMediaElement controls.
</Note>

## Render to video

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

<Steps>
  <Step title="Install the renderer">
    ```bash theme={null}
    npm install @helios-project/renderer
    ```
  </Step>

  <Step title="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}`);
    ```
  </Step>

  <Step title="Update package.json scripts">
    ```json theme={null}
    {
      "scripts": {
        "dev": "vite",
        "build": "vite build",
        "render": "npm run build && npx tsx render.ts"
      }
    }
    ```
  </Step>

  <Step title="Install tsx for running TypeScript">
    ```bash theme={null}
    npm install -D tsx
    ```
  </Step>

  <Step title="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`!
  </Step>
</Steps>

<Warning>
  Make sure your composition is built before rendering. The renderer needs the bundled files, not source files.
</Warning>

## 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

<CodeGroup>
  ```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
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Explore examples" icon="folder-open">
    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>

  <Card title="Learn the API" icon="book">
    Dive deeper into Helios capabilities:

    * Audio tracks and mixing
    * Captions and subtitles
    * Input props and schemas
    * Timeline markers
    * Distributed rendering
  </Card>

  <Card title="Framework integration" icon="layer-group">
    Use Helios with your preferred framework:

    * React with `useVideoFrame()` hook
    * Vue with composables
    * Svelte with stores
    * Solid.js integration
  </Card>

  <Card title="Production rendering" icon="server">
    Deploy Helios for scale:

    * Docker containerization
    * AWS Lambda distributed rendering
    * Google Cloud Run
    * Local orchestrator for parallel rendering
  </Card>
</CardGroup>

## 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

<Steps>
  <Step title="Start simple">
    Begin with basic shapes and movements. Add complexity gradually.
  </Step>

  <Step title="Use progress values">
    Convert frames to 0-1 progress for easier math:

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

  <Step title="Preview often">
    The dev server provides instant feedback. Use it liberally.
  </Step>

  <Step title="Expose to window">
    Always export `window.helios` so the player and renderer can control your composition.
  </Step>

  <Step title="Test different frame rates">
    30fps is standard, but try 60fps for smoother motion or 24fps for a cinematic feel.
  </Step>
</Steps>

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