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

# Solid integration

> Use Helios with Solid for fine-grained reactive video animations

Helios leverages Solid's fine-grained reactivity system through signals that efficiently update only when needed.

## Quick start

<Steps>
  <Step title="Install dependencies">
    ```bash theme={null}
    npm install @helios-project/core solid-js
    ```
  </Step>

  <Step title="Create the createHeliosSignal helper">
    ```js lib/createHeliosSignal.js theme={null}
    import { createSignal, onCleanup, onMount } from 'solid-js';

    export function createHeliosSignal(helios) {
        const [state, setState] = createSignal(helios.getState());

        onMount(() => {
            const unsub = helios.subscribe(setState);
            onCleanup(() => {
                unsub();
            });
        });

        return state;
    }
    ```
  </Step>

  <Step title="Initialize Helios">
    ```jsx index.jsx theme={null}
    import { render } from 'solid-js/web';
    import App from './App';
    import { Helios } from '@helios-project/core';

    // Initialize Helios
    const helios = new Helios({
        duration: 5,
        fps: 30,
        autoSyncAnimations: true
    });
    window.helios = helios;
    helios.bindToDocumentTimeline();

    render(() => <App />, document.getElementById('app'));
    ```
  </Step>

  <Step title="Create your first animation">
    ```jsx App.jsx theme={null}
    import { createMemo } from 'solid-js';
    import { createHeliosSignal } from './lib/createHeliosSignal';
    import './style.css';

    function App() {
        // Ensure helios exists (should be initialized in index.jsx)
        if (!window.helios) {
            console.warn('Helios not initialized on window');
        }

        const state = createHeliosSignal(window.helios);

        // Derived state for rotation (0 to 360 deg)
        const rotation = createMemo(() => {
            const s = state();
            const totalFrames = s.duration * window.helios.fps;
            const progress = totalFrames > 0 ? s.currentFrame / totalFrames : 0;
            return progress * 360;
        });

        return (
            <div class="container">
                <div class="column">
                    <h2>Signal Driven</h2>
                    <div
                        class="box signal-box"
                        style={{ transform: `rotate(${rotation()}deg)` }}
                    >
                        Signal
                    </div>
                </div>

                <div class="column">
                    <h2>CSS Driven</h2>
                    <div class="box css-box">
                        CSS
                    </div>
                </div>
            </div>
        );
    }

    export default App;
    ```
  </Step>
</Steps>

## Animation approaches

<Tabs>
  <Tab title="Signal-driven animations">
    Animate using Solid's reactive signals:

    ```jsx theme={null}
    import { createMemo } from 'solid-js';
    import { createHeliosSignal } from './lib/createHeliosSignal';

    function SignalAnimation() {
        const state = createHeliosSignal(window.helios);

        const opacity = createMemo(() => 
            Math.min(1, state().currentFrame / 30)
        );

        const transform = createMemo(() => {
            const frame = state().currentFrame;
            return `translateX(${frame * 5}px) rotate(${frame * 2}deg)`;
        });

        return (
            <div style={{ 
                opacity: opacity(), 
                transform: transform() 
            }}>
                Animated content
            </div>
        );
    }
    ```
  </Tab>

  <Tab title="Canvas animations">
    Use `createEffect` to draw frame-by-frame animations:

    ```jsx theme={null}
    import { createEffect } from 'solid-js';
    import { createHeliosSignal } from './lib/createHeliosSignal';
    import { Helios } from '@helios-project/core';

    // Initialize Helios if not already present
    if (!window.helios) {
        window.helios = new Helios({
            fps: 30,
            duration: 60,
            width: 1920,
            height: 1080,
            autoStart: true,
        });
    }

    function CanvasAnimation() {
        let canvasRef;
        const frame = createHeliosSignal(window.helios);

        createEffect(() => {
            const canvas = canvasRef;
            if (!canvas) return;

            const ctx = canvas.getContext('2d');
            if (!ctx) return;

            const state = frame();
            const { width, height, currentFrame, duration } = state;

            canvas.width = width;
            canvas.height = height;

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

            // Draw
            const totalFrames = duration * window.helios.fps;
            const progress = totalFrames > 0 ? currentFrame / totalFrames : 0;

            ctx.fillStyle = '#446b9e';
            const size = 200;
            const x = (width - size) * progress;
            const y = (height - size) / 2;

            ctx.fillRect(x, y, size, size);

            // Draw text
            ctx.fillStyle = 'white';
            ctx.font = '40px sans-serif';
            ctx.fillText(`Frame: ${currentFrame}`, 50, 100);
        });

        return (
            <canvas ref={canvasRef} style={{ width: '100%', height: 'auto' }} />
        );
    }
    ```
  </Tab>
</Tabs>

## Animation helpers

Helios provides utility functions for common animation patterns:

```jsx theme={null}
import { createMemo } from 'solid-js';
import { interpolate, spring } from '@helios-project/core';
import { createHeliosSignal } from './lib/createHeliosSignal';

function HelperDemo() {
    const state = createHeliosSignal(window.helios);

    // Interpolate x position: 0 -> 200 over frames 0-60
    const x = createMemo(() => 
        interpolate(state().currentFrame, [0, 60], [0, 200], { extrapolateRight: 'clamp' })
    );

    // Spring scale: 0 -> 1 starting at frame 0
    const scale = createMemo(() => 
        spring({ 
            frame: state().currentFrame, 
            fps: 30, 
            from: 0, 
            to: 1, 
            config: { stiffness: 100 } 
        })
    );

    return (
        <div style={{
            transform: `translateX(${x()}px) scale(${scale()})`,
            width: '100px',
            height: '100px',
            background: 'hotpink'
        }}>
            Animated
        </div>
    );
}
```

## Fine-grained reactivity

Solid's fine-grained reactivity means only the specific DOM nodes that depend on changing signals will update:

```jsx theme={null}
import { createMemo } from 'solid-js';
import { createHeliosSignal } from './lib/createHeliosSignal';

function FineGrainedExample() {
    const state = createHeliosSignal(window.helios);

    // Each memo creates a separate reactive computation
    const x = createMemo(() => state().currentFrame * 5);
    const y = createMemo(() => Math.sin(state().currentFrame * 0.1) * 100);
    const color = createMemo(() => {
        const hue = (state().currentFrame * 2) % 360;
        return `hsl(${hue}, 70%, 50%)`;
    });

    return (
        <>
            {/* Only the transform updates when x or y changes */}
            <div style={{ transform: `translate(${x()}px, ${y()}px)` }}>
                Box 1
            </div>

            {/* Only the background-color updates when color changes */}
            <div style={{ 'background-color': color() }}>
                Box 2
            </div>
        </>
    );
}
```

## Best practices

<AccordionGroup>
  <Accordion title="Initialize Helios globally">
    Create the Helios instance on `window` in your entry file for global access:

    ```jsx theme={null}
    // index.jsx
    import { Helios } from '@helios-project/core';

    const helios = new Helios({ duration: 5, fps: 30 });
    window.helios = helios;
    helios.bindToDocumentTimeline();
    ```
  </Accordion>

  <Accordion title="Use createMemo for derived values">
    Always use `createMemo` for computed animation values to ensure efficient updates:

    ```jsx theme={null}
    import { createMemo } from 'solid-js';

    const rotation = createMemo(() => {
        const progress = state().currentFrame / totalFrames;
        return progress * 360;
    });
    ```
  </Accordion>

  <Accordion title="Clean up subscriptions">
    Use `onMount` and `onCleanup` to manage Helios subscriptions:

    ```jsx theme={null}
    import { onMount, onCleanup } from 'solid-js';

    onMount(() => {
        const unsub = helios.subscribe(setState);
        onCleanup(() => {
            unsub();
        });
    });
    ```
  </Accordion>

  <Accordion title="Use createEffect for side effects">
    Use `createEffect` for canvas drawing and other side effects:

    ```jsx theme={null}
    import { createEffect } from 'solid-js';

    createEffect(() => {
        const ctx = canvas.getContext('2d');
        const currentFrame = state().currentFrame;
        // Draw based on currentFrame
    });
    ```
  </Accordion>
</AccordionGroup>

## TypeScript support

Helios provides full TypeScript support for Solid:

```tsx theme={null}
import type { Helios } from '@helios-project/core';
import { createSignal, onMount, onCleanup, type Accessor } from 'solid-js';

interface HeliosState {
    currentFrame: number;
    duration: number;
    fps: number;
}

export function createHeliosSignal(helios: Helios): Accessor<HeliosState> {
    const [state, setState] = createSignal<HeliosState>(helios.getState());

    onMount(() => {
        const unsub = helios.subscribe(setState);
        onCleanup(() => {
            unsub();
        });
    });

    return state;
}
```

## Performance benefits

Solid's fine-grained reactivity provides excellent performance for video animations:

* **No Virtual DOM**: Direct DOM updates mean less overhead
* **Surgical updates**: Only affected DOM nodes update
* **Automatic dependency tracking**: Solid knows exactly what needs to update
* **Compiled reactivity**: Reactive code is optimized at build time

## Next steps

<CardGroup cols={2}>
  <Card title="Animation helpers" icon="wand-magic-sparkles" href="/features/animation-helpers">
    Learn about interpolation, spring physics, and easing functions
  </Card>

  <Card title="Canvas rendering" icon="paintbrush" href="/guides/canvas">
    Create high-performance canvas animations
  </Card>

  <Card title="Sequences" icon="film" href="/guides/sequences">
    Build complex multi-scene animations
  </Card>

  <Card title="Export videos" icon="file-export" href="/guides/export">
    Render your animations to video files
  </Card>
</CardGroup>
