SDKs
JavaScript SDK
The @yak-io/javascript package provides the core client SDK and server handlers. It works with any JavaScript runtime that supports the Fetch API.
When to Use
- Building with non-React frameworks (Vue, Svelte, Solid, etc.)
- Need server handlers for custom runtimes (Cloudflare Workers, Deno, Bun)
- Building a custom integration without React components
For React apps, use @yak-io/react. For Next.js, use @yak-io/nextjs.
Installation
npm install @yak-io/javascriptpnpm add @yak-io/javascriptyarn add @yak-io/javascriptbun add @yak-io/javascriptServer Handlers
Create API endpoints that serve route configuration and handle tool calls:
import { createYakHandler } from "@yak-io/javascript/server";
const { GET, POST } = createYakHandler({
routes: [
{ path: "/", title: "Home" },
{ path: "/pricing", title: "Pricing" },
],
tools: [
{
id: "custom",
getTools: async () => [
{
name: "greet",
description: "Greet a user by name",
input_schema: {
type: "object",
properties: { name: { type: "string" } },
required: ["name"],
},
},
],
executeTool: async (name, args) => {
if (name === "greet") {
return { message: `Hello, ${args.name}!` };
}
throw new Error(`Unknown tool: ${name}`);
},
},
],
});
export { GET, POST };Route Schema
| Property | Type | Required | Description |
|---|---|---|---|
path | string | Yes | URL path |
title | string | No | Human-readable title |
description | string | No | Brief description for AI context |
Dynamic Route Sources
Fetch routes from external sources:
const cmsRoutes = {
id: "cms",
getRoutes: async () => {
const res = await fetch("https://cms.example.com/api/pages");
return res.json();
},
};
const { GET, POST } = createYakHandler({
routes: [staticRoutes, cmsRoutes],
});Client SDK
The YakClient class manages widget communication. For most use cases, use @yak-io/react or @yak-io/nextjs instead — this is the low-level API.
import { YakClient } from "@yak-io/javascript";
const client = new YakClient({
appId: "your-app-id",
onToolCall: async (name, args) => {
const res = await fetch("/api/yak", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, args }),
});
const data = await res.json();
if (!data.ok) throw new Error(data.error);
return data.result;
},
onReady: () => console.log("Widget ready"),
onClose: () => console.log("Widget closed"),
});
client.mount();
client.setWidgetOpen(true);
client.sendPrompt("Help me");
client.unmount();Configuration Options
| Option | Type | Description |
|---|---|---|
appId | string | Your Yak application ID |
onToolCall | (name, args) => Promise<unknown> | Tool execution handler |
onToolCallComplete | (event: ToolCallEvent) => void | Called after each tool call completes |
onRedirect | (path: string) => void | Navigation handler |
onReady | () => void | Called when the widget is ready |
onClose | () => void | Called when the widget is closed |
theme | Theme | Widget styling options |
Runtime Examples
Cloudflare Workers
import { createYakHandler } from "@yak-io/javascript/server";
const { GET, POST } = createYakHandler({
routes: [{ path: "/", title: "Home" }],
});
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/api/yak") {
if (request.method === "GET") return GET(request);
if (request.method === "POST") return POST(request);
}
return new Response("Not Found", { status: 404 });
},
};Hono
import { Hono } from "hono";
import { createYakHandler } from "@yak-io/javascript/server";
const app = new Hono();
const { GET, POST } = createYakHandler({
routes: [{ path: "/", title: "Home" }],
});
app.get("/api/yak", (c) => GET(c.req.raw));
app.post("/api/yak", (c) => POST(c.req.raw));
export default app;Deno
import { createYakHandler } from "@yak-io/javascript/server";
const { GET, POST } = createYakHandler({
routes: [{ path: "/", title: "Home" }],
});
Deno.serve(async (request) => {
const url = new URL(request.url);
if (url.pathname === "/api/yak") {
if (request.method === "GET") return GET(request);
if (request.method === "POST") return POST(request);
}
return new Response("Not Found", { status: 404 });
});Bun
import { createYakHandler } from "@yak-io/javascript/server";
const { GET, POST } = createYakHandler({
routes: [{ path: "/", title: "Home" }],
});
Bun.serve({
port: 3000,
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/yak") {
if (request.method === "GET") return GET(request);
if (request.method === "POST") return POST(request);
}
return new Response("Not Found", { status: 404 });
},
});Express / Node.js
import express from "express";
import { createYakHandler } from "@yak-io/javascript/server";
const app = express();
app.use(express.json());
const { GET, POST } = createYakHandler({
routes: [{ path: "/", title: "Home" }],
});
app.all("/api/yak", async (req, res) => {
const url = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
const request = new Request(url, {
method: req.method,
headers: req.headers as HeadersInit,
body: req.method !== "GET" ? JSON.stringify(req.body) : undefined,
});
const response = await (req.method === "POST" ? POST(request) : GET(request));
res.status(response.status);
response.headers.forEach((value, key) => res.setHeader(key, value));
res.send(Buffer.from(await response.arrayBuffer()));
});
app.listen(3000);TypeScript
Import types for your integrations:
// Client-side types
import type {
YakClientConfig,
Theme,
ThemeColors,
ToolCallHandler,
ToolCallEvent,
} from "@yak-io/javascript";
// Server-side types
import type {
RouteInfo,
RouteSource,
ToolDefinition,
ToolSource,
ToolExecutor,
ToolCallPayload,
ToolCallResult,
} from "@yak-io/javascript/server";