DEV Community

Stephen Bullocks
Stephen Bullocks

Posted on

I got tired of rewriting the same AI boilerplate so I built a library to fix it

Every time I added AI to a React app, I rewrote the same 200+ lines. Streaming loop. Manual message history. Tool call orchestration. Error handling. setIsLoading(false) only if I remembered.

After the third project I stopped and asked: why is nobody solving this the way RTK Query solved REST APIs?

So I built Strand (https://github.com/strand-js/strand).

Before

const [messages, setMessages] = useState([])
const [isLoading, setIsLoading] = useState(false)

async function send(text) {
setIsLoading(true)
manually stream tokens
manually detect tool calls
manually loop until done
setIsLoading(false) only if you remembered
}

After

const { messages, send, isPending, isStreaming, cancel } = useConversation({
system: 'You are a helpful assistant.',
})

Streaming, history, tool calls, cancellation, retry; all handled.

The thing nobody else has: useToolCall

Works from ANY component; no prop drilling
function WeatherStatus() {
const { status, input, output } = useToolCall('get_weather')

if (status === 'running') return <div>Checking {input?.location}…</div>
if (status === 'done') return <div>{output?.temp}°F</div>
return null
}

Live tool state: pending → running → done. Its observable anywhere in your tree.

Fixing the isLoading design flaw

The Vercel AI SDK has 4+ open issues (https://github.com/vercel/ai/issues) about isLoading getting stuck. The reason is architectural because "request sent" and "tokens arriving" are different states.

Strand tracks four:

const { isPending, isStreaming, isDone, error } = useConversation()
// isPending: waiting for first token
// isStreaming: tokens arriving
// isDone: just completed
// error: something failed

Works with Anthropic, OpenAI, and Google Gemini

npm install @strand-js/core @strand-js/react zod

npm install @strand-js/anthropic # or openai, or google

Swap providers by changing one server import. Zero frontend changes.

v0.1.8, MIT, open source.

https://github.com/strand-js/strand

Top comments (0)