Skip to content

Frontend SDKs / useStream compatibility ​

Connect your frontend to a running skein-js server with the standard LangChain SDKs. Use useStream to submit turns, read streamed messages, show errors, and respond to human-approval requests. You build the interface; the hook supplies the conversation state and actions.

Connect a React UI ​

Install the dedicated React package in your frontend:

bash
npm install @langchain/react @langchain/core

Start your skein-js server, then use its API URL and a registered Assistant ID. This example assumes the scaffolded echo graph and sends a known input:

tsx
"use client";
import { useStream } from "@langchain/react";

export function Chat() {
  const thread = useStream({
    apiUrl: "http://localhost:2024",
    assistantId: "echo", // replace with your graph's Assistant ID
  });

  return (
    <div>
      {thread.messages.map((message) => (
        <p key={message.id}>{typeof message.content === "string" ? message.content : ""}</p>
      ))}
      {thread.error != null && <p role="alert">{String(thread.error)}</p>}
      <button
        disabled={thread.isLoading}
        onClick={() => void thread.submit({ messages: [{ role: "user", content: "hello" }] })}
      >
        Send hello
      </button>
      {thread.isLoading && <button onClick={() => void thread.stop()}>Stop</button>}
    </div>
  );
}

Choose Send hello and expect echo: hello in the conversation. A browser on a different origin needs the server's CORS policy to allow your frontend. For custom authentication, follow the authentication recipe.

The nextjs-app example serves both UI and protocol from one origin. For a complete application with tools, reasoning output, and approval cards, see chat-app.

Handle pauses and failures ​

When your graph calls interrupt(), render its request from thread.interrupt and respond with the value your graph expects. For a graph expecting { approved: boolean }, an approval button can call:

tsx
<button onClick={() => void thread.respond({ approved: true })}>Approve</button>

Use the matching rejection value on another test thread and verify that the action is not performed. See human-in-the-loop for the graph and SDK examples.

Show thread.error to the user and inspect the run before retrying an ambiguous request. Call thread.stop() when the user wants to cancel. Unmounting the UI or reopening a conversation does not cancel or start a run by itself. Test restoration and multiple turns with your application's thread-selection controls.

Choose a client ​

Your applicationClient
Node, a service, or a testClient from @langchain/langgraph-sdk
ReactuseStream from @langchain/react
An existing legacy React integration@langchain/langgraph-sdk/react remains supported
A ready-made chat frontendAgent Chat UI
Interactive graph developmentThe console or LangGraph Studio

For a JavaScript SDK smoke test with assertions and cleanup, see Testing your project.

Vue, Svelte, and Angular ​

Use the dedicated framework packages, not SDK subpaths such as @langchain/langgraph-sdk/vue:

FrameworkPackageEntry pointsTested peer range
React@langchain/reactuseStream, StreamProviderReact 18–19
Vue@langchain/vueuseStream, provideStream, LangChainPluginVue 3
Svelte@langchain/svelteuseStream, provideStream, getStreamSvelte 5
Angular@langchain/angularinjectStreamAngular 18–21

Use each package's framework-specific setup. The compatibility reference lists the versions exercised with skein-js and known media limitations. There are no standalone skein-js Vue, Svelte, or Angular example applications yet.

Version and streaming reference ​

The React examples use @langchain/react 1.2.7 and SDK 1.12.7. React, Angular, Vue, and Svelte 1.2.6 are also verified combinations. Treat these as tested versions, rather than a guarantee about every future client release.

Svelte 1.2.6's root useImages selector returns an empty projection; use the scoped selector for the subgraph namespace containing media. Vue 1.2.6 proxies media assets, so unwrap an asset before reading its blob:

ts
import { toRaw } from "vue";

const blob = await toRaw(images.value[0]).blob;

Dedicated framework bindings use thread event subscriptions and commands. The legacy React hook uses run-based streaming. Both use HTTP/SSE; no WebSocket configuration is required. See streaming if you implement a custom client.

Working example ​

react-usestream is a minimal Next.js application. Start its graph server and UI using its README, send two turns, reopen the conversation, and check that state is restored without another execution. Repeat with your own graph before building a larger interface.

References ​