--- title: Methods description: Access scope methods with useAui. --- Methods are the imperative API of a scope. They're the functions your resource returns: `increment`, `send`, `delete`, or anything else. You access them through `useAui()`. ## Defining methods First, register the method signatures in `ScopeRegistry`: ```ts title="lib/store/counter-scope.ts" import "@assistant-ui/store"; declare module "@assistant-ui/store" { interface ScopeRegistry { counter: { methods: { increment: () => void; decrement: () => void; reset: () => void; }; }; } } ``` Then create a resource that implements them. The return type `ClientOutput<"counter">` ties the resource to the scope: TypeScript will error if the returned methods don't match the registry: ```ts title="lib/store/counter-resource.ts" import { resource } from "@assistant-ui/tap"; import { useState } from "react"; import type { ClientOutput } from "@assistant-ui/store"; const useCounterResource = (): ClientOutput<"counter"> => { const [count, setCount] = useState(0); return { increment: () => setCount((c) => c + 1), decrement: () => setCount((c) => c - 1), reset: () => setCount(0), }; }; const CounterResource = resource(useCounterResource); ``` Every function you return becomes a method on the scope. There's nothing special about them: they're plain functions that can call `useState` setters, trigger side effects, or do anything else. ## useAui Call `useAui()` with no arguments inside any `AuiProvider` to get the current store: ```tsx const aui = useAui(); ``` The returned object has a property for every scope available in the current context. Crucially, `useAui()` does **not** re-render your component when scopes change: it returns a stable reference. The actual scope is only resolved when you call `aui.counter()`. ## Scope resolution `aui.counter` is not the scope itself, it's an accessor. The scope resolves when you call it: ```tsx // resolves the counter scope, returns its methods aui.counter().increment(); ``` This distinction matters. The `aui` object is stable across re-renders and scope changes. When a derived scope switches which item it points to, `aui` stays the same, but `aui.counter()` returns the new scope's methods. This is why you should always resolve at the point of use: ```tsx const MessageActions = () => { const aui = useAui(); return (