Use Genkit in a Next.js app
This page shows how you can use Genkit flows in your Next.js applications using the official Genkit Next.js plugin. For complete API reference documentation, see the Genkit Next.js Plugin API Reference.
Before you begin
You should be familiar with Genkit’s concept of flows, and how to write them.
Create a Next.js project
If you don’t already have a Next.js project that you want to add generative AI features to, you can create one for the purpose of following along with this page:
npx create-next-app@latest
Install Genkit dependencies
Install the Genkit dependencies into your Next.js app:
-
Install the core Genkit library and the Next.js plugin:
Terminal window npm install genkit @genkit-ai/next -
Install at least one model plugin.
For example, to use Google AI:
Terminal window npm install @genkit-ai/googleaiOr to use Vertex AI:
Terminal window npm install @genkit-ai/vertexai -
Install the Genkit CLI globally. The tsx tool is also recommended as a development dependency, as it makes testing your code more convenient. Both of these dependencies are optional, however.
Terminal window npm install -g genkit-clinpm install --save-dev tsx
Define Genkit flows
Create a new directory in your Next.js project to contain your Genkit flows. For example, create src/genkit/
and add your flow definitions there:
For example, create src/genkit/menuSuggestionFlow.ts
:
import { googleAI } from '@genkit-ai/googleai';import { genkit } from 'genkit';
const ai = genkit({ plugins: [googleAI()],});
export const menuSuggestionFlow = ai.defineFlow('menuSuggestionFlow', async (restaurantTheme, streamingCallback) => { const { text } = await ai.generate({ model: googleAI.model('gemini-2.0-flash'), prompt: `Invent a menu item for a ${restaurantTheme} themed restaurant.`, streamingCallback: (chunk) => streamingCallback?.(chunk.text), }); return text;});
Create API routes
Now, create API routes that expose your flows using the Genkit Next.js plugin. For each flow, create a corresponding route file:
Create src/app/api/menuSuggestion/route.ts
:
import { menuSuggestionFlow } from '@/genkit/menuSuggestionFlow';import { appRoute } from '@genkit-ai/next';
export const POST = appRoute(menuSuggestionFlow);
Call your flows from the frontend
In your frontend code, you can now call your flows using the Genkit Next.js client:
'use client';
import { useState } from 'react';import { runFlow, streamFlow } from '@genkit-ai/next/client';import { menuSuggestionFlow } from '@/genkit/menuSuggestionFlow';
export default function Home() { const [menuItem, setMenuItem] = useState<string>(''); const [isLoading, setIsLoading] = useState(false); const [streamedText, setStreamedText] = useState<string>('');
async function getMenuItem(formData: FormData) { const theme = formData.get('theme')?.toString() ?? ''; setIsLoading(true);
try { // Regular (non-streaming) approach const suggestion = await runFlow<typeof menuSuggestionFlow>({ url: '/api/menuSuggestion', input: theme, });
setMenuItem(suggestion); } catch (error) { console.error('Error generating menu item:', error); } finally { setIsLoading(false); } }
async function streamMenuItem(formData: FormData) { const theme = formData.get('theme')?.toString() ?? ''; setIsLoading(true); setStreamedText('');
try { // Streaming approach const result = streamFlow<typeof menuSuggestionFlow>({ url: '/api/menuSuggestion', input: theme, });
// Process the stream chunks as they arrive for await (const chunk of result.stream()) { setStreamedText((prev) => prev + chunk.output); }
// Get the final complete response const finalOutput = await result.output(); setMenuItem(finalOutput); } catch (error) { console.error('Error streaming menu item:', error); } finally { setIsLoading(false); } }
return ( <main> <form action={getMenuItem}> <label htmlFor="theme">Suggest a menu item for a restaurant with this theme: </label> <input type="text" name="theme" id="theme" /> <br /> <br /> <button type="submit" disabled={isLoading}> Generate </button> <button type="button" disabled={isLoading} onClick={(e) => { e.preventDefault(); const formData = new FormData(e.currentTarget.form); streamMenuItem(formData); }} > Stream Generation </button> </form> <br />
{streamedText && ( <div> <h3>Streaming Output:</h3> <pre>{streamedText}</pre> </div> )}
{menuItem && ( <div> <h3>Final Output:</h3> <pre>{menuItem}</pre> </div> )} </main> );}
Authentication (Optional)
If you need to add authentication to your API routes, you can pass headers with your requests:
const result = await runFlow<typeof menuSuggestionFlow>({ url: '/api/menuSuggestion', headers: { Authorization: 'Bearer your-token-here', }, input: theme,});
Test your app locally
If you want to run your app locally, you need to make credentials for the model API service you chose available.
-
Generate an API key for the Gemini API using Google AI Studio.
-
Set the
GEMINI_API_KEY
environment variable to your key:Terminal window export GEMINI_API_KEY=<your API key>
-
In the Cloud console, Enable the Vertex AI API for your project.
-
Set some environment variables and use the
gcloud
tool to set up application default credentials:Terminal window export GCLOUD_PROJECT=<your project ID>export GCLOUD_LOCATION=us-central1gcloud auth application-default login
Then, run your app locally as normal:
npm run dev
For Genkit development tools, you can still use:
genkit start -- npx tsx --watch src/genkit/menuSuggestionFlow.ts
Deploy your app
When you deploy your app, you will need to make sure the credentials for any external services you use (such as your chosen model API service) are available to the deployed app. See the following pages for information specific to your chosen deployment platform: