Svelte / SvelteKit

Initialize once in your root layout inside an $effect — it only runs in the browser, and the cleanup handles hot reloads and teardown. This site is built exactly this way.

svelte
<!-- src/routes/+layout.svelte -->
<script>
  import Vivace from 'vivace-css'
  import 'vivace-css/vivace.css'

  let { children } = $props()

  $effect(() => {
    Vivace.init()
    return () => Vivace.destroy()
  })
</script>

{@render children()}

Then annotate any element, in any component:

svelte
<h1 data-viv="@fd @sl-y_ease-out-expo">Hello</h1>

<ul data-viv="@fd_child-ascend" data-viv-on="appearing">
  {#each items as item}
    <li>{item}</li>
  {/each}
</ul>

Route changes & dynamic content

Client-side navigation mounts new DOM — the MutationObserver registers it automatically, so data-viv-on="load" elements animate on every page you navigate to, and appearing elements arm themselves. No per-page code.

SSR

The module is SSR-safe: importing it on the server is a no-op (every API call guards on document). Import the CSS in the layout so server-rendered pages ship the styles with the first paint.

Programmatic control

svelte
<script>
  import Vivace from 'vivace-css'

  let box
</script>

<div bind:this={box} data-viv="@pop">…</div>
<button onclick={() => Vivace.trigger(box)}>replay</button>
Portrait of Axel RAKOTOARIVAO
Created by
Axel RAKOTOARIVAO
MIT — keyframe DSL inspired by A.css
bun add vivace-css