LangGraph Tutorial (TypeScript): streaming agent responses for beginners

By Cyprian AaronsUpdated 2026-04-22
langgraphstreaming-agent-responses-for-beginnerstypescript

This tutorial shows you how to build a LangGraph agent in TypeScript that streams tokens as they are generated. You need this when your app must show partial responses immediately instead of waiting for the full model output.

What You'll Need

  • Node.js 18+
  • A TypeScript project
  • @langchain/langgraph
  • @langchain/openai
  • @langchain/core
  • An OpenAI API key set as OPENAI_API_KEY
  • A terminal that can run ts-node, tsx, or compiled Node output

Install the packages:

npm install @langchain/langgraph @langchain/openai @langchain/core
npm install -D typescript tsx @types/node

Step-by-Step

  1. Create a small graph state and a single agent node. For beginners, keep the graph simple: one node calls the model, and the graph streams the result back to your terminal.
import { ChatOpenAI } from "@langchain/openai";
import {
  Annotation,
  MessagesAnnotation,
  StateGraph,
  START,
  END,
} from "@langchain/langgraph";

const llm = new ChatOpenAI({
  model: "gpt-4o-mini",
  temperature: 0,
  streaming: true,
});

const GraphState = Annotation.Root({
  messages: MessagesAnnotation.spec,
});
  1. Add a node that invokes the model with the current messages. This node returns an updated message list, which LangGraph uses to track state across execution.
async function agentNode(state: typeof GraphState.State) {
  const response = await llm.invoke(state.messages);
  return {
    messages: [response],
  };
}
  1. Wire the node into a LangGraph workflow. This is the minimum graph you need for streaming: start at the agent, then end after one pass.
const graph = new StateGraph(GraphState)
  .addNode("agent", agentNode)
  .addEdge(START, "agent")
  .addEdge("agent", END)
  .compile();
  1. Stream events from the graph execution. Use streamMode: "messages" so you can print token-level output as it arrives.
async function main() {
  const input = {
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: "Explain streaming in one sentence." },
    ],
  };

  const stream = await graph.stream(input, { streamMode: "messages" });

  for await (const [chunk] of stream) {
    const token = chunk.content;
    if (typeof token === "string" && token.length > 0) {
      process.stdout.write(token);
    }
  }

  process.stdout.write("\n");
}

main().catch(console.error);
  1. Put it all together in one file and run it. Save this as streaming-agent.ts so you can execute it directly.
import { ChatOpenAI } from "@langchain/openai";
import {
  Annotation,
  MessagesAnnotation,
  StateGraph,
  START,
  END,
} from "@langchain/langgraph";

const llm = new ChatOpenAI({
  model: "gpt-4o-mini",
  temperature: 0,
});

const GraphState = Annotation.Root({
  messages: MessagesAnnotation.spec,
});

async function agentNode(state: typeof GraphState.State) {
  const response = await llm.invoke(state.messages);
  return { messages: [response] };
}

const graph = new StateGraph(GraphState)
  .addNode("agent", agentNode)
  .addEdge(START, "agent")
  .addEdge("agent", END)
  .compile();

async function main() {
  const stream = await graph.stream(
    {
      messages: [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: "Give me a short answer about LangGraph streaming." },
      ],
    },
    { streamMode: "messages" }
  );

  for await (const [chunk] of stream) {
    if (typeof chunk.content === "string") process.stdout.write(chunk.content);
  }

  process.stdout.write("\n");
}

main().catch(console.error);

Testing It

Run the file with npx tsx streaming-agent.ts. If everything is wired correctly, you should see the response appear gradually in your terminal instead of all at once.

If nothing streams, check three things first: your OPENAI_API_KEY, whether your model supports streaming, and whether you used streamMode: "messages". If you get a type error, make sure your package versions are aligned and that you're using the current LangGraph TypeScript APIs.

A good sanity check is to ask for a longer answer, like “Write five bullet points about observability.” Short answers may look like they arrived all at once because there were only a few tokens.

Next Steps

  • Add tool calling so the streamed agent can fetch data before answering.
  • Split the graph into multiple nodes for planning, retrieval, and response generation.
  • Stream into a web UI with Server-Sent Events or WebSockets instead of printing to stdout.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides