Quickstart

Send your first message in under 5 minutes. No credentials, no server, no backend needed.

Prefer to build with an AI coding agent? Skip to the Vibe Coding Guide for a step-by-step walkthrough with Claude Code, Codex, or Antigravity.

Prerequisites

  • Node.js 20+ installed
  • A new or existing TypeScript project
  • The SDK installed (see Installation)

Quick sanity check before you go further — most "weird install failures" trace back to a missing tool or a version that's too old:

node --version     # v20.0.0 or newer
corepack enable    # makes pnpm available; safe to re-run
pnpm --version     # 9.15.0 or newer

Step 1: Create a chat client

The simplest possible setup uses the mock transport, which simulates AI responses locally.

import { createChatClient } from 'gecx-chat';
import { createMockTransport } from 'gecx-chat/testing';

const client = createChatClient({
  transport: createMockTransport(),
});

That's it. No API keys, no auth configuration, no server endpoint. The mock transport returns realistic streaming responses for development.

Step 2: Start a session and send a message

const session = await client.createSession();
const result = await session.send('What products do you recommend?');

for (const msg of result.messages) {
  for (const part of msg.parts) {
    if (part.type === 'text') {
      console.log(part.text);
    }
  }
}

Expected output:

I'd be happy to help you find the right product! Here are some of our top recommendations...

The SDK normalizes every response into typed message parts. Each part has a type field (text, markdown, citation, suggestion-chips, product-carousel, etc.) so you always know what you're rendering.

Step 3: Add a client tool

Client tools let the AI call functions in your app. Define a tool with a JSON Schema for its input:

import { defineClientTool } from 'gecx-chat';

const lookupOrder = defineClientTool({
  name: 'lookup_order',
  description: 'Look up an order by ID',
  inputSchema: {
    type: 'object',
    required: ['orderId'],
    properties: {
      orderId: { type: 'string', description: 'The order ID to look up' },
    },
  },
  execute: async ({ orderId }) => {
    return { orderId, status: 'shipped', eta: '2025-03-15' };
  },
});

Pass it when creating the client:

const client = createChatClient({
  transport: createMockTransport(),
  tools: [lookupOrder],
});

When the AI decides to call lookup_order, the SDK validates the input against your schema, runs your execute function, and sends the result back to the AI automatically.

Step 4: Handle errors

Every SDK error is a ChatSdkError with a machine-readable code, a UI-safe userMessage, and a developerHint for debugging:

import { ChatSdkError } from 'gecx-chat';

try {
  await session.send('Where is order ORD-1234?');
} catch (error) {
  if (error instanceof ChatSdkError) {
    console.log(error.code);          // e.g. 'TRANSPORT_CONNECT_FAILED'
    console.log(error.userMessage);    // safe to show in the UI
    console.log(error.developerHint); // detailed info for logs
    console.log(error.retryable);      // true if you can retry
  }
}

See the Error Codes Reference for every error code and its remediation.

Complete example

Here's everything together in a single file:

import { createChatClient, defineClientTool, ChatSdkError } from 'gecx-chat';
import { createMockTransport } from 'gecx-chat/testing';

// 1. Define a tool
const lookupOrder = defineClientTool({
  name: 'lookup_order',
  description: 'Look up an order by ID',
  inputSchema: {
    type: 'object',
    required: ['orderId'],
    properties: { orderId: { type: 'string' } },
  },
  execute: async ({ orderId }) => {
    return { orderId, status: 'shipped', eta: '2025-03-15' };
  },
});

// 2. Create the client
const client = createChatClient({
  transport: createMockTransport(),
  tools: [lookupOrder],
});

// 3. Start a session and send a message
const session = await client.createSession();

try {
  const result = await session.send('What products do you recommend?');

  for (const msg of result.messages) {
    for (const part of msg.parts) {
      if (part.type === 'text') console.log(part.text);
      if (part.type === 'suggestion-chips') console.log('Suggestions:', part.chips);
    }
  }
} catch (error) {
  if (error instanceof ChatSdkError) {
    console.error(`[${error.code}] ${error.userMessage}`);
  }
}

// 4. Clean up
await client.shutdown();

What's next

Source: docs/getting-started/quickstart.md