Genkit is a framework for building AI-powered applications. This is the API reference for the Genkit JS libraries. For tutorials and guides, visit genkit.dev.
Install the following Genkit dependencies to use Genkit in your project:
genkit — Genkit core capabilities.@genkit-ai/google-genai for Google AI Gemini models.npm install genkit @genkit-ai/google-genai
Set up your API key:
export GOOGLE_API_KEY=your-api-key
Make your first request:
import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
const ai = genkit({ plugins: [googleAI()] });
const { text } = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Why is Genkit awesome?',
});
console.log(text);
This reference documents the following packages:
| Package | Description |
|---|---|
| genkit | Core framework — generation, flows, tools, prompts, streaming, and more. |
| @genkit-ai/google-genai | Google AI (Gemini) model plugin. |
| @genkit-ai/vertexai | Vertex AI model plugin. |
| @genkit-ai/firebase | Firebase integration (auth, Firestore, Cloud Functions). |
| @genkit-ai/express | Serve flows as Express endpoints. |
| @genkit-ai/google-cloud | Google Cloud monitoring and telemetry. |
| @genkit-ai/next | Next.js integration. |
| @genkit-ai/checks | Google Checks safety evaluation plugin. |
| @genkit-ai/dev-local-vectorstore | Local vector store for development. |
| @genkit-ai/evaluators | Built-in evaluators for testing AI output quality. |
| @genkit-ai/ollama | Ollama local model plugin. |
| @genkit-ai/chroma | ChromaDB vector store plugin. |
| @genkit-ai/pinecone | Pinecone vector store plugin. |
| @genkit-ai/mcp | Model Context Protocol (MCP) plugin. |
| @genkit-ai/anthropic | Anthropic (Claude) model plugin. |
| @genkit-ai/compat-oai | OpenAI-compatible model plugin. |
| @genkit-ai/fetch | HTTP fetch utilities for plugins. |
| @genkit-ai/middleware | Model middleware plugin (retry, caching, etc.). |
The genkit package also provides subpath imports for specific functionality:
| Import | Purpose |
|---|---|
genkit |
Main entry — Genkit class, generate, defineFlow, defineTool, schemas, types |
genkit/beta |
Beta features including interrupts (defineInterrupt) |
genkit/beta/client |
Client-side helpers (runFlow, streamFlow) |
genkit/model/middleware |
Model middleware (retry, fallback, augmentWithContext, etc.) |
genkit/plugin |
Plugin authoring utilities (model, embedder, retriever, etc.) |
genkit/model |
Model types and helpers |
genkit/embedder |
Embedder types |
genkit/retriever |
Retriever and indexer types |
genkit/reranker |
Reranker types |
genkit/evaluator |
Evaluator types |
genkit/tool |
Tool types |
genkit/schema |
Schema utilities |
Generate strongly-typed, schema-validated output using Zod schemas:
import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
const ai = genkit({ plugins: [googleAI()] });
const RecipeSchema = z.object({
title: z.string(),
ingredients: z.array(z.string()),
instructions: z.array(z.string()),
});
const { output } = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Invent a new pasta recipe',
output: { schema: RecipeSchema },
});
console.log(output?.title); // fully typed
Stream responses in real time with generateStream:
const { response, stream } = ai.generateStream({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Write a short story about a robot',
});
for await (const chunk of stream) {
process.stdout.write(chunk.text);
}
Define tools that models can call automatically to access external data or perform actions:
const getWeather = ai.defineTool(
{
name: 'getWeather',
description: 'Gets the current weather for a given city',
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({ temperature: z.number(), condition: z.string() }),
},
async ({ city }) => {
// your implementation here
return { temperature: 72, condition: 'sunny' };
}
);
const { text } = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'What should I wear in Tokyo today?',
tools: [getWeather],
});
Beta feature: Interrupts require importing from
genkit/betainstead ofgenkit:import { genkit } from 'genkit/beta';
Interrupts pause model processing and return control to the caller, enabling human-in-the-loop workflows. There are two patterns:
Use defineInterrupt to create a tool that always pauses. The caller provides a response with .respond():
const confirmAction = ai.defineInterrupt({
name: 'confirmAction',
description: 'Confirm an action with the user before proceeding',
inputSchema: z.object({ action: z.string(), reason: z.string() }),
outputSchema: z.object({ approved: z.boolean() }),
});
let response = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Book a table for 2 at 7pm tonight',
tools: [confirmAction],
});
// The model triggered an interrupt — get user approval
if (response.interrupts.length) {
const interrupt = response.interrupts[0];
console.log(interrupt.toolRequest.input); // { action: '...', reason: '...' }
// Resume with the user's response (bypasses tool execution)
response = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
messages: response.messages,
tools: [confirmAction],
resume: {
respond: confirmAction.respond(interrupt, { approved: true }),
},
});
}
Regular tools can conditionally interrupt using interrupt() and be re-executed with .restart(). The resumed flag lets the tool know it's been approved:
const sendEmail = ai.defineTool(
{
name: 'sendEmail',
description: 'Sends an email',
inputSchema: z.object({ to: z.string(), body: z.string() }),
outputSchema: z.object({ sent: z.boolean() }),
},
async (input, { interrupt, resumed }) => {
if (!resumed) {
interrupt({ message: `Send email to ${input.to}?` });
}
// Approved — proceed with sending
return { sent: true };
}
);
let response = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Send a hello email to alice@example.com',
tools: [sendEmail],
});
if (response.interrupts.length) {
const interrupt = response.interrupts[0];
// Restart re-executes the tool, this time with resumed=true
response = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
messages: response.messages,
tools: [sendEmail],
resume: { restart: [sendEmail.restart(interrupt)] },
});
}
Manage prompts as code with embedded schemas, model configuration, and Handlebars templating:
---
model: googleai/gemini-flash-latest
input:
schema:
topic: string
output:
schema:
title: string
summary: string
---
Write a blog post about {{topic}}.
const blogPrompt = ai.prompt('blog');
const { output } = await blogPrompt({ topic: 'AI safety' });
Build strongly typed, fully observable workflows that can be served as APIs and accessed from the client:
import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
const ai = genkit({
plugins: [googleAI()],
model: googleAI.model('gemini-flash-latest'),
});
const RecipeSchema = z.object({
title: z.string(),
ingredients: z.array(z.string()),
instructions: z.array(z.string()),
});
export const recipeFlow = ai.defineFlow(
{
name: 'recipeFlow',
inputSchema: z.object({ ingredient: z.string() }),
outputSchema: RecipeSchema,
},
async (input) => {
const { output } = await ai.generate({
prompt: `Create a recipe using ${input.ingredient}`,
output: { schema: RecipeSchema },
});
if (!output) throw new Error('Failed to generate recipe');
return output;
}
);
Serve flows as an API:
import { startFlowServer } from '@genkit-ai/express'; // npm i @genkit-ai/express
startFlowServer({ flows: [recipeFlow] });
Access from the client:
import { streamFlow } from 'genkit/beta/client';
const { stream } = streamFlow({
url: 'http://localhost:3500/recipeFlow',
input: { ingredient: 'avocado' },
});
for await (const chunk of stream) {
console.log(chunk);
}
Add common functionality to your AI requests with middleware (available in genkit/model/middleware and @genkit-ai/middleware):
import { retry } from 'genkit/model/middleware';
const { text } = await ai.generate({
model: googleAI.model('gemini-flash-latest'),
prompt: 'Why is Genkit awesome?',
use: [
retry({
maxRetries: 3,
initialDelayMs: 1000,
backoffFactor: 2,
}),
],
});