# Using a framework

The objects are framework-free on purpose: a class that takes an element. Every framework can hand one over. The pattern is always the same: create on mount, update when options change, destroy on unmount.

The quickest way is the wrapper that ships in every package: `wrappers/react.mjs`, `vue.mjs`, `svelte.mjs`, or `element.mjs` for a custom element that works in Angular, Astro or a plain page. On any piece's page, pick your framework in the Code tab and it writes the example with your settings. Below is what the wrappers do for you, if you'd rather wire it yourself.

## React

```jsx
import { useEffect, useRef } from 'react';
import { Odometer } from './odometer/odometer.mjs';
import './odometer/odometer.css';

export function Seats({ value }) {
  const host = useRef(null);
  const odo = useRef(null);

  useEffect(() => {
    odo.current = new Odometer(host.current, { value, digits: 3 });
    return () => odo.current.destroy();
  }, []);

  useEffect(() => { odo.current?.setValue(value); }, [value]);

  return <div ref={host} />;
}
```

In Next.js, put `'use client'` at the top of the file: the objects draw in the browser.

## Vue

```vue
<script setup>
import { onMounted, onBeforeUnmount, ref, watch } from 'vue';
import { Iris } from './iris/iris.mjs';
import './iris/iris.css';

const props = defineProps({ open: Number });
const host = ref(null);
let iris;

onMounted(() => { iris = new Iris(host.value, { driver: 'manual' }); });
watch(() => props.open, (v) => iris?.open(v));
onBeforeUnmount(() => iris?.destroy());
</script>

<template><div ref="host"><img src="/work.jpg" alt="The project"></div></template>
```

## Svelte

```svelte
<script>
  import { onMount } from 'svelte';
  import { PinScreen } from './pin-screen/pin-screen.mjs';
  import './pin-screen/pin-screen.css';

  export let text = 'HELLO';
  let host, board;

  onMount(() => {
    board = new PinScreen(host, { text });
    return () => board.destroy();
  });
  $: board?.update({ text });
</script>

<div bind:this={host} style="height: 420px"></div>
```

## Astro

```astro
<div id="vessel" style="height: 360px"></div>
<link rel="stylesheet" href="/vessel/vessel.css" />
<script>
  import { Vessel } from '../vessel/vessel.mjs';
  new Vessel(document.getElementById('vessel'), { level: 0.62 });
</script>
```

## Server rendering

The objects touch `window`, `document` and the canvas, so construct them only in the browser: in an effect, `onMount`, a client script or behind a dynamic import. Rendering the empty host element on the server is fine; it is what the object fills.
