Skip to main content
Helios integrates beautifully with Svelte’s reactive system through stores that automatically update your animations.

Quick start

1

Install dependencies

npm install @helios-project/core svelte
2

Create the Helios store

lib/store.js
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;
    });
};
3

Create your first animation

App.svelte
<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>

Animation approaches

Animate Svelte components using reactive store subscriptions:
<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>

Animation helpers

Helios provides utility functions for common animation patterns:
<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:
<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:
<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

Create readable stores for Helios state to prevent accidental modifications:
import { readable } from 'svelte/store';

export const createHeliosStore = (helios) => {
    return readable(helios.getState(), (set) => {
        const unsubscribe = helios.subscribe(set);
        return unsubscribe;
    });
};
Leverage Svelte’s $: reactive statements for derived animation values:
<script>
  $: progress = $heliosStore.currentFrame / (duration * fps);
  $: rotation = progress * 360;
  $: scale = 1 + Math.sin(progress * Math.PI) * 0.5;
</script>
Always remove event listeners in onDestroy:
<script>
  import { onMount, onDestroy } from 'svelte';

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

  onDestroy(() => {
    window.removeEventListener('resize', handleResize);
  });
</script>
Use Svelte’s style: directive for dynamic inline styles:
<div 
  style:transform={`rotate(${rotation}deg)`}
  style:opacity={opacity}
>
  Content
</div>

TypeScript support

Helios works seamlessly with Svelte and TypeScript:
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

Animation helpers

Learn about interpolation, spring physics, and easing functions

Canvas rendering

Create high-performance canvas animations

Sequences

Build complex multi-scene animations

Export videos

Render your animations to video files

Build docs developers (and LLMs) love