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

# Vue example

> Build Helios compositions with Vue composables and reactive data

This example demonstrates how to build a Helios composition using Vue 3. It showcases Vue-specific patterns including composables for frame synchronization and reactive template bindings.

## Setup

Install Helios core and Vue dependencies:

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

## Implementation

### Composable for frame synchronization

Create a composable to subscribe to Helios frame updates:

```typescript theme={null}
// composables/useVideoFrame.ts
import { ref, onUnmounted, type Ref } from 'vue';
import type { Helios } from '@helios-project/core';

export function useVideoFrame(helios: Helios): Ref<number> {
    const frame = ref(helios.getState().currentFrame);

    const update = (state: { currentFrame: number }) => {
        frame.value = state.currentFrame;
    };

    const unsubscribe = helios.subscribe(update);

    onUnmounted(() => {
        unsubscribe();
    });

    return frame;
}
```

The composable uses Vue's `ref` to create a reactive frame reference and `onUnmounted` to handle cleanup when the component is destroyed.

### Main component

Build your composition using Vue's template syntax and the `useVideoFrame` composable:

```vue theme={null}
<!-- App.vue -->
<script setup lang="ts">
import { Helios } from '@helios-project/core';
import { useVideoFrame } from './composables/useVideoFrame';

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

// Expose to window for debugging/player control
if (typeof window !== 'undefined') {
    (window as any).helios = helios;
}

const frame = useVideoFrame(helios);
</script>

<template>
  <div class="container">
    <div
        class="box"
        :style="{
            opacity: Math.min(1, frame / 30),
            transform: `scale(${Math.min(1.5, 0.5 + frame / 150)}) rotate(${frame * 2}deg)`
        }"
    >
        Vue DOM
    </div>
    <div class="info">Frame: {{ frame.toFixed(2) }}</div>
  </div>
</template>

<style scoped>
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: white;
    font-family: sans-serif;
}
.box {
    width: 200px;
    height: 200px;
    background-color: #42b883;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    font-weight: bold;
    border-radius: 20px;
    box-shadow: 0 0 20px rgba(66, 184, 131, 0.5);
    border: 4px solid #35495e;
}
.info {
    margin-top: 2rem;
    font-size: 1.5rem;
}
</style>
```

## Key Vue patterns

### Composable-based state management

The `useVideoFrame` composable encapsulates Helios subscription logic using Vue's Composition API. It returns a reactive `ref` that automatically triggers re-renders when the frame changes.

### Dynamic style bindings

Use Vue's `:style` binding to apply dynamic animations. Calculations happen in the template, keeping the component concise and reactive.

### Script setup syntax

The `<script setup>` syntax provides a clean, TypeScript-friendly way to define component logic without boilerplate. Variables and imports are automatically available in the template.

### Scoped styles

Scoped styles ensure CSS only applies to this component, preventing style leakage while maintaining clean separation between logic and presentation.

## Usage

Run the development server:

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

The composition will render with reactive frame updates. The Helios instance is exposed on `window.helios` for debugging and player control.
