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

# Svelte integration

> Use Helios with Svelte for reactive video animations

Helios integrates beautifully with Svelte's reactive system through stores that automatically update your animations.

## Quick start

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

  <Step title="Create the Helios store">
    ```js lib/store.js theme={null}
    import { readable } from 'svelte/store';

    export const createHeliosStore = (helios) => {
        return readable(helios.getState(), (set) => {
            set(helios.getState());
            const unsubscribe = helios.subscribe((state) => {
                set(state);
            });
            return unsubscribe;
        });
    };
    ```
  </Step>

  <Step title="Create your first animation">
    ```svelte App.svelte theme={null}
    <script>
      import { onMount } from 'svelte';
      import { Helios } from '@helios-project/core';
      import { createHeliosStore } from './lib/store';

      const duration = 5;
      const fps = 30;

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

      helios.bindToDocumentTimeline();

      if (typeof window !== 'undefined') {
        window.helios = helios;
      }

      const heliosStore = createHeliosStore(helios);
    </script>

    <div class="container">
        <div
            class="box"
            style:opacity={$heliosStore.currentFrame / (duration * fps)}
            style:transform={`rotate(${$heliosStore.currentFrame * 2}deg)`}
        >
            Svelte DOM
        </div>
    </div>

    <style>
      :global(body) {
        margin: 0;
        overflow: hidden;
        background-color: #111;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100vh;
      }
      .box {
        width: 200px;
        height: 200px;
        background-color: royalblue;
        color: white;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 24px;
        font-family: sans-serif;
        border-radius: 10px;
      }
    </style>
    ```
  </Step>
</Steps>

## Animation approaches

<Tabs>
  <Tab title="DOM animations">
    Animate Svelte components using reactive store subscriptions:

    ```svelte theme={null}
    <script>
      import { createHeliosStore } from './lib/store';

      const heliosStore = createHeliosStore(helios);
    </script>

    <div
      style:opacity={Math.min(1, $heliosStore.currentFrame / 30)}
      style:transform={`translateX(${$heliosStore.currentFrame * 5}px) rotate(${$heliosStore.currentFrame * 2}deg)`}
    >
      Animated content
    </div>
    ```
  </Tab>

  <Tab title="Canvas animations">
    Use reactive statements to draw frame-by-frame animations:

    ```svelte theme={null}
    <script>
      import { onMount, onDestroy } from 'svelte';
      import { Helios } from '@helios-project/core';
      import { createHeliosStore } from './lib/store';

      let canvas;
      let ctx;
      const duration = 5;
      const fps = 30;

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

      helios.bindToDocumentTimeline();

      if (typeof window !== 'undefined') {
        window.helios = helios;
      }

      const heliosStore = createHeliosStore(helios);

      // Reactive drawing
      $: if (ctx && $heliosStore) {
        draw($heliosStore.currentFrame);
      }

      function draw(currentFrame) {
          const time = currentFrame / fps * 1000;
          const progress = (time % (duration * 1000)) / (duration * 1000);

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

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

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

          // Draw moving circle
          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();
      }

      const resizeCanvas = () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        if (ctx && $heliosStore) {
          draw($heliosStore.currentFrame);
        }
      };

      onMount(() => {
        ctx = canvas.getContext('2d');
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
      });

      onDestroy(() => {
         if (typeof window !== 'undefined') {
            window.removeEventListener('resize', resizeCanvas);
         }
      });

    </script>

    <canvas bind:this={canvas} style="display: block; width: 100%; height: 100%;"></canvas>

    <style>
      :global(body) {
        margin: 0;
        overflow: hidden;
        background-color: #111;
      }
    </style>
    ```
  </Tab>
</Tabs>

## Animation helpers

Helios provides utility functions for common animation patterns:

```svelte theme={null}
<script>
  import { interpolate, spring } from '@helios-project/core';
  import { createHeliosStore } from './lib/store';

  const heliosStore = createHeliosStore(helios);

  // Reactive computed values
  $: x = interpolate($heliosStore.currentFrame, [0, 60], [0, 200], { extrapolateRight: 'clamp' });
  $: scale = spring({ 
    frame: $heliosStore.currentFrame, 
    fps: 30, 
    from: 0, 
    to: 1, 
    config: { stiffness: 100 } 
  });
</script>

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

## Svelte 5 runes

For Svelte 5, you can use runes for reactive state:

```svelte theme={null}
<script>
  import { Helios } from '@helios-project/core';

  let frame = $state(0);

  const helios = new Helios({ duration: 5, fps: 30 });
  helios.bindToDocumentTimeline();

  helios.subscribe((state) => {
    frame = state.currentFrame;
  });

  let progress = $derived(frame / (5 * 30));
  let rotation = $derived(progress * 360);
</script>

<div style:transform={`rotate(${rotation}deg)`}>
  Svelte 5 Animation
</div>
```

## Sequencing patterns

Create sequences manually using reactive statements:

```svelte theme={null}
<script>
  import { createHeliosStore } from './lib/store';

  const heliosStore = createHeliosStore(helios);

  // Define sequences
  $: sequence1Active = $heliosStore.currentFrame >= 0 && $heliosStore.currentFrame < 30;
  $: sequence2Active = $heliosStore.currentFrame >= 30 && $heliosStore.currentFrame < 60;
  $: sequence3Active = $heliosStore.currentFrame >= 60 && $heliosStore.currentFrame < 90;
</script>

{#if sequence1Active}
  <div class="box red">Sequence 1</div>
{/if}

{#if sequence2Active}
  <div class="box blue">Sequence 2</div>
{/if}

{#if sequence3Active}
  <div class="box green">Sequence 3</div>
{/if}
```

## Best practices

<AccordionGroup>
  <Accordion title="Use readable stores">
    Create readable stores for Helios state to prevent accidental modifications:

    ```js theme={null}
    import { readable } from 'svelte/store';

    export const createHeliosStore = (helios) => {
        return readable(helios.getState(), (set) => {
            const unsubscribe = helios.subscribe(set);
            return unsubscribe;
        });
    };
    ```
  </Accordion>

  <Accordion title="Use reactive statements for animations">
    Leverage Svelte's `$:` reactive statements for derived animation values:

    ```svelte theme={null}
    <script>
      $: progress = $heliosStore.currentFrame / (duration * fps);
      $: rotation = progress * 360;
      $: scale = 1 + Math.sin(progress * Math.PI) * 0.5;
    </script>
    ```
  </Accordion>

  <Accordion title="Clean up event listeners">
    Always remove event listeners in `onDestroy`:

    ```svelte theme={null}
    <script>
      import { onMount, onDestroy } from 'svelte';

      onMount(() => {
        window.addEventListener('resize', handleResize);
      });

      onDestroy(() => {
        window.removeEventListener('resize', handleResize);
      });
    </script>
    ```
  </Accordion>

  <Accordion title="Use style directives">
    Use Svelte's `style:` directive for dynamic inline styles:

    ```svelte theme={null}
    <div 
      style:transform={`rotate(${rotation}deg)`}
      style:opacity={opacity}
    >
      Content
    </div>
    ```
  </Accordion>
</AccordionGroup>

## TypeScript support

Helios works seamlessly with Svelte and TypeScript:

```ts theme={null}
import type { Helios } from '@helios-project/core';
import type { Readable } from 'svelte/store';
import { readable } from 'svelte/store';

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

export function createHeliosStore(helios: Helios): Readable<HeliosState> {
    return readable(helios.getState(), (set) => {
        const unsubscribe = helios.subscribe((state) => {
            set(state);
        });
        return unsubscribe;
    });
}
```

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