# Resources
URL: /tap/docs/tap/resources

Package stateful behavior into reusable, configurable values.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

A **Resource** packages stateful behavior behind a JavaScript value. It renders with inputs, keeps Hook state between renders, mounts effects, and cleans up when it unmounts.

Its return value is its public API: the state and methods available wherever the Resource is rendered.

## Package a Hook as a Resource

Start with an ordinary Hook, then pass it to `resource()`:

```
import { resource } from "@assistant-ui/tap";
import { useState } from "react";

const useCounter = (props: { initialValue?: number }) => {
  const [count, setCount] = useState(props.initialValue ?? 0);

  return { count, increment: () => setCount((c) => c + 1) };
};

const Counter = resource(useCounter);
```

`useCounter` contains the implementation. `Counter` is the reusable Resource. Keep the implementation in a `use`-prefixed Hook so React's rules of Hooks lint it normally.

Calling a Resource configures it:

```
const counter = Counter({ initialValue: 10 });
```

This does not run `useCounter` or create state. It returns an inert `ResourceElement` describing what to render, much like JSX describes a component before React renders it.

## Configuration is a value

Because a configured Resource is a value, an application can choose, pass, and nest it before any state is created:

```
import { useResource, type ResourceElement } from "@assistant-ui/tap";

type CounterState = ReturnType<typeof useCounter>;

function CounterButton({
  counter = Counter({ initialValue: 0 }),
}: {
  counter?: ResourceElement<CounterState>;
}) {
  const state = useResource(counter);

  return <button onClick={state.increment}>{state.count}</button>;
}
```

The component owns where the state is rendered without owning its implementation or configuration. A caller can use the default or provide any other Resource that returns the same API.

## Hosting a Resource

Use `useResource` to render a single Resource, or [`useResources`](/tap/docs/tap/composition#useresources) to render a keyed list of Resources.

```
import { useResource } from "@assistant-ui/tap";

function CounterButton() {
  const { count, increment } = useResource(Counter({ initialValue: 10 }));
  return <button onClick={increment}>Count: {count}</button>;
}
```

Rendering creates the Resource's state and returns its current public API. In a React component, the component re-renders when that state changes and the Resource unmounts with the component. Inside another Resource, it becomes a child in the same resource tree.

Arguments can change across renders without replacing the Resource's state. Effects respond through their dependency arrays, just as they do in a React component.

## Next

- [Composition](/tap/docs/tap/composition): compose individual resources and keyed lists.
- [Trees & Re-renders](/tap/docs/tap/trees-and-rerenders): give a resource tree its own scheduler with `useTapRoot`.
- [Context](/tap/docs/tap/context): pass values through the resource tree without prop drilling.