Skip to content

Repository files navigation

Next.js + ADK TypeScript starter site

A minimal starter for building agentic AI web applications with Google’s ADK framework for TypeScript and Next.js.

  • Define and run your agents all in TypeScript!
  • Unopinionated boilerplate. Based off standard create-next-app, customise according to your preferences.
  • Collocation. No separate backend service needed if you're building a Next.js app.
  • Flexible model choice. Use Gemini models or other models with an extensible wrapper class API.

Agent Development Kit (ADK) for TypeScript:

an open-source, code-first TypeScript toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control

Try now:

Open in StackBlitz Open with CodeSandbox Open in GitHub Codespaces

Tech Stack

  • ADK TypeScript
  • Google GenAI SDK
  • Next.js
  • Tailwind CSS
  • Biome
  • Drizzle

Getting Started

Prerequisites

Installation

  1. Clone repo (or "Use this template" from GH web)

    git clone https://github.com/ekafyi/starter-nextjs-adk-js.git my-app
    cd my-app
  2. Install packages

    npm install
  3. Copy env file and fill GEMINI_API_KEY with your credentials

    cp .env.example .env
    nano .env
  4. Setup local database (default to local.db)

    npm run db:push
    npm run db:seed
  5. Run Next.js dev server (default on localhost:3000)

    npm run dev

ADK Web UI

ADK Web: "the built-in developer UI that is integrated with Agent Development Kit for easier agent development and debugging."

Run ADK dev server (default on localhost:8000):

npx adk web src/agents
# or:
npm run adk-web-ui

⚠️ Not meant for production, for dev and debug only.

adk web ui showing user and assistant conversation and tool usage

Project Structure

src
├── agents/          # Agent definitions
├── app/
│   ├── agent/       # Frontend route `/agent`
│   └── api/
│       └── agent/   # API route `/api/agent`
├── db/              # DB schema and client
├── lib/
│   ├── data/        # Mock external data
│   ├── auth.ts      # Mock user auth
│   └── countries.ts # Mock external services call

# Everything else is standard app router Next.js.

Usage

Defining Agents

📄 src/agents/agent.ts

export const rootAgent = new LlmAgent({
  name: "countries_agent",
  model: "gemini-2.5-flash",
  description: "Agent to answer questions about ...",
  // ... etc
});

Defining Tools

📄 src/agents/agent.ts

const getCapital = new FunctionTool({
  name: "get_country_capital",
  description: "Retrieves the capital city for a country.",
  parameters: z.object({ /* ... zod schema ... */ }),
  execute: async ({ country }) => {
    return await getMockCapital(country);
  },
});

const getFlag = new FunctionTool({
  name: "get_country_flag",
  // ... etc
});

export const rootAgent = new LlmAgent({
  // ... 
  tools: [getCapital, getFlag],
});

Use optional ToolContext to read/write session-scoped state.

- execute: async ({ country }) => {
+ execute: async ({ country }, toolContext?: ToolContext) => {
+  toolContext?.state.set("last_mentioned_country", country);
    // ...
},

Passing Agent to Runner

📄 src/app/api/agent/route.ts

// Initialize runner with the agent
const runner = new InMemoryRunner({
  agent: rootAgent,
  appName: "sample_app"
});

// ... inside POST route handler ...
const iterator = runner.runAsync({
  userId,
  sessionId,
  newMessage: createUserContent(message),
});

User Auth

Bring your own auth.

  1. Replace the placeholder (store and check for "username" cookie) with your own.
  2. Replace imports from lib/auth.

Persistence

Currently ADK TypeScript has no built-in support for persistence; everything runs in-memory.

Here I use Drizzle and local SQLite file to persist user sessions and events manually.

Local vs Remote DB:

  • Local file works out of the box for running locally.

    • (optional) Define DB file name through the DB_FILE_NAME env variable (default to local.db).
    • npm run db:push creates the DB file and apply the schema.
    • (optional) npm run db:seed inserts sample user to the DB.
  • If deploying this to a serverless hosting service, use a compatible remote database like Turso. Local file will not persist across serverless function invocations.

    • Change the DB_FILE_NAME env variable to a libsql:// URL for production.
    • Make sure to seed the remote DB by running db:seed.

Learn More

License

MIT

About

Next.js + ADK TypeScript starter site

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages