Skip to content

Quick Start

An AI agent browsing products, adding to cart, and writing a review — all through the SLOP protocol. Run it yourself: bun demo

Your app exposes a state tree — a semantic description of what it is and what it can do. AI subscribes to the tree, receives patches as things change, and triggers actions directly on the nodes they belong to. No screenshots, no blind tool calls.

Terminal window
bun add @slop-ai/client @slop-ai/react
// slop.ts — one instance, import anywhere
import { createSlop } from "@slop-ai/client";
export const slop = createSlop({ id: "my-app", name: "My App" });

Place useSlop next to your state, not in JSX. Each call registers a node in the tree.

import { action, useSlop } from "@slop-ai/react";
import { slop } from "./slop";
function TodoList() {
const [todos, setTodos] = useState([
{ id: "1", title: "Read the SLOP spec", done: true },
{ id: "2", title: "Build the MVP", done: false },
]);
useSlop(slop, "todos", () => ({
type: "collection",
props: { count: todos.length },
items: todos.map(todo => ({
id: todo.id,
props: { title: todo.title, done: todo.done },
actions: {
toggle: action(() => setTodos(prev =>
prev.map(t => t.id === todo.id ? { ...t, done: !t.done } : t)
)),
delete: action(
() => setTodos(prev => prev.filter(t => t.id !== todo.id)),
{ dangerous: true },
),
},
})),
}));
return <ul>{todos.map(t => <li key={t.id}>{t.title}</li>)}</ul>;
}

That code produces this tree — it’s what the AI sees:

[root] My App
[collection] todos (count=2)
[item] todo-1 (title="Read the SLOP spec", done=true) actions: [toggle, delete]
[item] todo-2 (title="Build the MVP", done=false) actions: [toggle, delete]

The AI subscribes, receives patches when state changes, and invokes toggle or delete on the exact node. Your component re-renders as usual — SLOP doesn’t touch your UI.

Want to experiment? Try it in the playground →

Install the SLOP browser extension. It discovers your provider automatically, opens a floating chat overlay, and lets you inspect the live tree in an expandable drawer. You can chat with the AI and watch it read state and invoke actions.

If you want AI responses instead of tree inspection only, configure an LLM profile first. The extension ships with a default local Ollama profile, and the Installation and Chrome Extension docs show how to switch to OpenAI, OpenRouter, or Gemini.

Your components SLOP engine AI consumer
───────────────── ────────────── ──────────────
useSlop("todos", ...) → assembles tree → subscribes
useSlop("settings",..) → diffs on change → receives patches
→ pushes patches → invokes actions
→ routes invokes → sees updated tree
← handler runs ←

Each component registers its own slice. Components don’t know about each other. When a component unmounts, its nodes disappear.

SLOP works with any framework — and on the server in any language.

StackGuide
Vue / Solid / Angular / SvelteVue, Solid, Angular, Svelte
Vanilla JSUse @slop-ai/client directly
Server-backed web app (Express, Fastify, Hono)Server & Native Apps
Fullstack (TanStack Start)TanStack Start
Python (FastAPI, CLI, desktop)Python guide
Go (net/http, CLI, daemons)Go guide
Rust (axum, CLI, embedded)Rust guide
Build an AI consumerConsumer guide