DEV Community

Cover image for I Built a Full-Stack AI Agent App in 48 Hours Using React 19 + TypeScript. Here's Exactly How.
Emma Schmidt
Emma Schmidt

Posted on

I Built a Full-Stack AI Agent App in 48 Hours Using React 19 + TypeScript. Here's Exactly How.

No tutorials covered this end-to-end. So I documented every step.


Everyone is talking about AI agents in 2026. Very few are showing you how to actually ship one. I spent a weekend building a production-ready AI agent app using the hottest stack right now: React 19, TypeScript, Server Actions, and a multi-agent backend. No fluff. No theory. Just the steps that worked.

By the end of this post, you will have a working blueprint you can fork and ship today.


Why This Stack, Why Now

TypeScript became the most-used language on GitHub by contributor count in 2025, surpassing Python by roughly 42,000 contributors. Nearly every major framework now scaffolds in TypeScript by default, meaning developers adopting those frameworks are automatically working in TypeScript from day one.

And on the AI side? 84% of developers now use AI coding tools, and 51% of professionals reach for them every single day.

The shift is real. The developers winning right now are not writing more code. They are orchestrating smarter systems. Let's build one.


What We Are Building

A multi-agent task manager that:

  • Accepts a plain-English goal from the user
  • Breaks it into subtasks using an AI planner agent
  • Executes each subtask with a specialist agent
  • Streams results back to the UI in real time

This is not a chatbot. This is an agentic app with real architecture.


Step 1: Scaffold the Project

npx create-next-app@latest agent-app --typescript --app
cd agent-app
npm install ai @ai-sdk/anthropic zod
Enter fullscreen mode Exit fullscreen mode

Use the App Router. Server Actions are a first-class citizen here and they will save you from writing a dozen API routes.

Project structure:
/app

/actions <- Server Actions (agent logic lives here)

/components <- React 19 UI components

/api <- Only for streaming endpoints

/lib

agents.ts <- Agent definitions and orchestration

schema.ts <- Zod schemas for structured outputs


Step 2: Define Your Agent Schema with Zod

Structured outputs are the backbone of reliable agents. If your agent returns raw prose, you cannot build UI on top of it.

// lib/schema.ts
import { z } from "zod";

export const TaskPlanSchema = z.object({
  goal: z.string(),
  subtasks: z.array(
    z.object({
      id: z.string(),
      title: z.string(),
      agent: z.enum(["researcher", "writer", "reviewer"]),
      instructions: z.string(),
    })
  ),
});

export type TaskPlan = z.infer<typeof TaskPlanSchema>;
Enter fullscreen mode Exit fullscreen mode

This locks the AI output into a predictable shape. No more JSON.parse roulette.


Step 3: Build the Planner Agent (Server Action)

// app/actions/planner.ts
"use server";

import { generateObject } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { TaskPlanSchema } from "@/lib/schema";

export async function planGoal(goal: string) {
  const { object } = await generateObject({
    model: anthropic("claude-sonnet-4-6"),
    schema: TaskPlanSchema,
    prompt: `
      You are a project planner. Break this goal into 3-5 concrete subtasks.
      Assign each to the most suitable specialist agent.
      Goal: ${goal}
    `,
  });

  return object;
}
Enter fullscreen mode Exit fullscreen mode

Server Actions in React 19 mean you call this directly from your component. No fetch, no API route, no boilerplate.


Step 4: Build the Specialist Agents

// lib/agents.ts
import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";

const AGENT_PROMPTS = {
  researcher: "You are a research agent. Find facts, cite sources, summarize.",
  writer: "You are a writing agent. Produce clear, structured content.",
  reviewer: "You are a review agent. Check for accuracy, gaps, and quality.",
};

export async function runAgent(
  agentType: keyof typeof AGENT_PROMPTS,
  instructions: string
) {
  const { text } = await generateText({
    model: anthropic("claude-sonnet-4-6"),
    system: AGENT_PROMPTS[agentType],
    prompt: instructions,
  });

  return text;
}
Enter fullscreen mode Exit fullscreen mode

Each agent has a focused role. The mental model has shifted: the 10x engineer is no longer someone who writes more code. It is someone who effectively orchestrates agents that do. Your architecture should reflect that.


Step 5: Orchestrate with a Server Action

// app/actions/orchestrate.ts
"use server";

import { planGoal } from "./planner";
import { runAgent } from "@/lib/agents";

export async function runGoal(goal: string) {
  const plan = await planGoal(goal);

  const results = await Promise.all(
    plan.subtasks.map(async (task) => {
      const output = await runAgent(task.agent, task.instructions);
      return { ...task, output };
    })
  );

  return { plan, results };
}
Enter fullscreen mode Exit fullscreen mode

Notice Promise.all. Subtasks run in parallel. This is how you get fast agents instead of slow sequential chains.


Step 6: Build the React 19 UI

// app/components/AgentRunner.tsx
"use client";

import { useState, useTransition } from "react";
import { runGoal } from "@/app/actions/orchestrate";

export function AgentRunner() {
  const [goal, setGoal] = useState("");
  const [results, setResults] = useState<any>(null);
  const [isPending, startTransition] = useTransition();

  function handleRun() {
    startTransition(async () => {
      const data = await runGoal(goal);
      setResults(data);
    });
  }

  return (
    <div className="max-w-2xl mx-auto p-6">
      <h1 className="text-2xl font-bold mb-4">AI Agent Runner</h1>

      <input
        value={goal}
        onChange={(e) => setGoal(e.target.value)}
        placeholder="Enter your goal..."
        className="w-full border rounded p-2 mb-4"
      />

      <button
        onClick={handleRun}
        disabled={isPending}
        className="bg-blue-600 text-white px-4 py-2 rounded"
      >
        {isPending ? "Running agents..." : "Run"}
      </button>

      {results && (
        <div className="mt-6 space-y-4">
          {results.results.map((r: any) => (
            <div key={r.id} className="border rounded p-4">
              <p className="font-semibold">{r.title}</p>
              <p className="text-sm text-gray-500 mb-2">Agent: {r.agent}</p>
              <p className="text-sm">{r.output}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

useTransition gives you pending state for free. No loading spinners wired by hand. The React Compiler reduces unnecessary re-renders by 25-40% with zero developer effort. The performance wins come for free here.


Step 7: Add Error Boundaries and Fallbacks

Agents fail. Models timeout. Networks drop. This is not optional.

// app/components/AgentErrorBoundary.tsx
"use client";

import { ErrorBoundary } from "react-error-boundary";

function Fallback({ error }: { error: Error }) {
  return (
    <div className="text-red-600 border border-red-300 p-4 rounded">
      <p className="font-semibold">Agent failed</p>
      <p className="text-sm">{error.message}</p>
    </div>
  );
}

export function SafeAgentRunner({ children }: { children: React.ReactNode }) {
  return (
    <ErrorBoundary FallbackComponent={Fallback}>{children}</ErrorBoundary>
  );
}
Enter fullscreen mode Exit fullscreen mode

Wrap your AgentRunner in SafeAgentRunner. Done.


Step 8: Deploy to Vercel in 3 Minutes

npx vercel --prod
Enter fullscreen mode Exit fullscreen mode

That is it. Vercel handles Edge Functions, Server Actions, and streaming natively. No config. No YAML files. No crying at 2am.


The Architecture at a Glance

User Input
|
v
Planner Agent (Server Action)
|
v
Task Plan (Zod-validated JSON)
|
v
Parallel Specialist Agents
[Researcher] [Writer] [Reviewer]
|
v
Streamed Results -> React 19 UI

Clean. Typed. Parallel. Production-ready.


What To Build Next

This blueprint scales. Swap in different agent types, add memory with a vector store, plug in tool use for web search or code execution. The architecture holds.

If you want to skip the setup entirely and work with a team of senior engineers who handle end-to-end product development, from architecture to deployment, covering React, React Native, Node.js, and AI-integrated builds for startups and scale-ups, that option exists and it moves faster than you think.

But if you are building it yourself, you now have the foundation.

Key Takeaways

  • React 19 Server Actions replace 90% of your API layer
  • TypeScript + Zod is the only sane way to build with LLMs
  • Parallel agent execution is not advanced, it is table stakes
  • useTransition gives you pending UI without any extra state
  • Deploy to Vercel, move on, iterate fast

What are you building with AI agents? Drop it in the comments. I read every one.


If this saved you time, drop a reaction. It helps more developers find it.

Top comments (0)