Skip to content

Svelte

Terminal window
bun add @slop-ai/client @slop-ai/svelte

Create a browser-side provider once and reuse it across components:

import { createSlop } from "@slop-ai/client";
export const slop = createSlop({
id: "notes-app",
name: "Notes App",
});

@slop-ai/svelte exports a Svelte 5 composable that tracks rune-based state and unregisters automatically on component destroy.

<script lang="ts">
import { action, useSlop } from "@slop-ai/svelte";
import { slop } from "./slop";
interface Note {
id: string;
title: string;
pinned: boolean;
}
let notes = $state<Note[]>([]);
useSlop(slop, "notes", () => ({
type: "collection",
props: { count: notes.length },
actions: {
create: action({ title: "string" }, ({ title }) => {
notes = [...notes, { id: crypto.randomUUID(), title, pinned: false }];
}),
clear_all: action(() => {
notes = [];
}, { dangerous: true }),
},
items: notes.map((note) => ({
id: note.id,
props: { title: note.title, pinned: note.pinned },
actions: {
toggle_pin: action(() => {
notes = notes.map((entry) =>
entry.id === note.id ? { ...entry, pinned: !entry.pinned } : entry,
);
}),
},
})),
}));
</script>

The package publishes a .svelte.ts entrypoint so downstream Svelte tooling keeps compiling rune syntax correctly. You still author normal Svelte 5 code, but the adapter handles registration, updates, and cleanup in the right lifecycle.