Firebase Genkit is a powerful framework for building AI-powered applications with TypeScript. This codelab will guide you through three essential patterns for working with Genkit: basic AI generation, prompt management with .prompt files, and building reusable flows.
📚 Additional Resources:
ai.generate API for direct AI interactions.prompt files📚 Additional Resources:
By the end of this codelab, you'll have built three practical business examples:
ai.generate.prompt filesBefore we start building, let's set up a new Genkit project.
First, create a new directory and initialize a Node.js project:
mkdir genkit-workshop
cd genkit-workshop
npm init -y
First, install the Genkit CLI globally:
npm install -g genkit-cli
Then, add the following packages to your project:
npm install genkit @genkit-ai/google-genai
npm install -D typescript tsx @types/node
Create a tsconfig.json file:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Create a .env file in your project root:
# Get your API key from https://aistudio.google.com/apikey
GEMINI_API_KEY=your_google_ai_api_key_here
Important: Never commit your API keys to version control. Create a .gitignore file:
node_modules/
.env
dist/
*.log
npm install dotenv
Let's make sure everything is working correctly:
# Check Node.js version (should be 18+)
node --version
# Check npm version
npm --version
# Verify TypeScript compilation works
npx tsc --version
If any command fails, please install the missing dependencies using the links provided above.
📚 Additional Resources:
Let's start with the simplest way to use Genkit: direct AI generation using the ai.generate API.
Create src/example1-basic.ts:
import { googleAI } from '@genkit-ai/google-genai';
import { genkit } from 'genkit';
import 'dotenv/config';
// Initialize Genkit with Google AI
const ai = genkit({
plugins: [googleAI()],
model: 'gemini-2.5-flash',
});
async function basicGeneration() {
try {
// Simple text generation
const response = await ai.generate({
prompt: 'Write a short welcome message for a new team member joining our development team.',
});
console.log('Generated message:');
console.log(response.text());
} catch (error) {
console.error('Error generating content:', error);
}
}
// Run the example
basicGeneration();
Execute the basic generation example:
npx tsx src/example1-basic.ts
You should see a generated welcome message!
Let's try a few more simple examples. Update src/example1-basic.ts:
import { googleAI } from '@genkit-ai/google-genai';
import { genkit } from 'genkit';
import 'dotenv/config';
// Initialize Genkit with Google AI
const ai = genkit({
plugins: [googleAI()],
model: 'gemini-2.5-flash',
});
async function basicGeneration() {
try {
// Example 1: Generate a welcome message
console.log('=== Welcome Message ===');
const welcomeResponse = await ai.generate({
prompt: 'Write a short welcome message for a new team member joining our development team.',
});
console.log(welcomeResponse.text());
// Example 2: Create a simple task list
console.log('\n=== Task List ===');
const taskResponse = await ai.generate({
prompt: 'Create a simple 3-item todo list for setting up a new development environment.',
});
console.log(taskResponse.text());
// Example 3: Write a brief explanation
console.log('\n=== Explanation ===');
const explanationResponse = await ai.generate({
prompt: 'Explain what TypeScript is in 2-3 simple sentences.',
});
console.log(explanationResponse.text());
} catch (error) {
console.error('Error generating content:', error);
}
}
// Run the example
basicGeneration();
Start Firebase Studio to test your generation interactively:
genkit start -- tsx --watch src/index.ts
This will open the Genkit Developer UI in your browser where you can test your AI generation with different prompts and see the results in real-time.
📚 Additional Resources:
Managing prompts in separate files makes them more maintainable and allows for better collaboration. Let's create a simple story generator using .prompt files.
Create a directory for prompts at your project root and add your first prompt file:
mkdir prompts
Create prompts/story-generator.prompt:
---
model: googleai/gemini-2.5-flash
input:
schema:
character: string
setting: string
---
Write a short, fun story (2-3 paragraphs) about {{character}} in {{setting}}.
Keep it light-hearted and suitable for all ages.
Create src/example2-prompts.ts:
import { googleAI } from '@genkit-ai/google-genai';
import { genkit } from 'genkit';
import 'dotenv/config';
// Initialize Genkit with Google AI
const ai = genkit({
plugins: [googleAI()],
});
// Load the prompt from the file
const storyGeneratorPrompt = ai.prompt('story-generator');
async function generateStory() {
try {
console.log('=== Generating Story with Prompt File ===');
const storyInput = {
character: 'a friendly robot',
setting: 'a magical library',
};
console.log('Story parameters:');
console.log(`Character: ${storyInput.character}`);
console.log(`Setting: ${storyInput.setting}`);
const response = await storyGeneratorPrompt(storyInput);
console.log('\n=== Generated Story ===');
console.log(response.text());
} catch (error) {
console.error('Error generating story:', error);
}
}
// Generate different stories
async function generateDifferentStories() {
const stories = [
{ character: 'a curious cat', setting: 'a space station' },
{ character: 'a young wizard', setting: 'a bustling marketplace' },
{ character: 'a brave explorer', setting: 'an underwater city' },
];
for (const story of stories) {
console.log(`\n=== Story: ${story.character} in ${story.setting} ===`);
const response = await storyGeneratorPrompt(story);
console.log(response.text());
console.log('\n' + '='.repeat(50));
}
}
// Run examples
async function main() {
await generateStory();
await generateDifferentStories();
}
main();
Let's create another prompt for generating simple recipes. Create prompts/recipe-generator.prompt:
---
model: googleai/gemini-2.5-flash
input:
schema:
ingredient: string
mealType: string
---
Create a simple recipe for {{mealType}} using {{ingredient}} as the main ingredient.
Keep it easy to follow with basic ingredients and simple steps.
Run the prompt-based example:
npx tsx src/example2-prompts.ts
You should see several different stories generated using your prompt file!
With the Developer UI running (genkit start -- tsx --watch src/index.ts), you can see your prompts listed in the interface and test them with different inputs interactively.
📚 Additional Resources:
Flows are reusable functions that can be called, tested, and monitored. They're perfect for building simple AI workflows.
Create src/example3-flows.ts:
import { googleAI } from '@genkit-ai/google-genai';
import { genkit, z } from 'genkit';
import 'dotenv/config';
// Initialize Genkit with Google AI
const ai = genkit({
plugins: [googleAI()],
model: 'gemini-2.5-flash',
});
// Define a simple greeting flow
export const greetingFlow = ai.defineFlow(
{
name: 'greeting',
inputSchema: z.object({
name: z.string().describe("The person's name"),
language: z.enum(['english', 'spanish', 'french']).describe('Language for greeting'),
}),
outputSchema: z.object({
greeting: z.string().describe('The generated greeting'),
}),
},
async ({ name, language }) => {
// Generate the greeting
const response = await ai.generate({
prompt: `Create a friendly greeting for ${name} in ${language}. Keep it warm and welcoming.`,
});
return {
greeting: response.text().trim(),
};
},
);
// Define a joke generator flow
export const jokeFlow = ai.defineFlow(
{
name: 'jokeGenerator',
inputSchema: z.object({
topic: z.string().describe('The topic for the joke'),
}),
outputSchema: z.object({
joke: z.string().describe('The generated joke'),
}),
},
async ({ topic }) => {
// Generate a clean, family-friendly joke
const response = await ai.generate({
prompt: `Create a clean, family-friendly joke about ${topic}. Keep it short and funny.`,
});
return {
joke: response.text().trim(),
};
},
);
// Example usage function
async function demonstrateFlows() {
try {
console.log('=== Testing Greeting Flow ===');
const greetingResult = await greetingFlow({
name: 'Alice',
language: 'english',
});
console.log('Greeting Result:');
console.log(greetingResult.greeting);
console.log('\n=== Testing Joke Flow ===');
const jokeResult = await jokeFlow({
topic: 'programming',
});
console.log('Joke Result:');
console.log(jokeResult.joke);
console.log('\n=== Testing Multiple Greetings ===');
const people = [
{ name: 'Bob', language: 'spanish' as const },
{ name: 'Claire', language: 'french' as const },
];
for (const person of people) {
const result = await greetingFlow(person);
console.log(`${person.name} (${person.language}): ${result.greeting}`);
}
} catch (error) {
console.error('Error running flows:', error);
}
}
// Run the demonstration
demonstrateFlows();
### Create a package.json script
Add a script to your `package.json` to easily run the flows:
```json
{
"scripts": {
"example1": "tsx src/example1-basic.ts",
"example2": "tsx src/example2-prompts.ts",
"example3": "tsx src/example3-flows.ts",
"studio": "genkit start"
}
}
Run the flows example:
npm run example3
Start the Developer UI and navigate to the Flows section:
genkit start -- tsx --watch src/index.ts
In the Developer UI, you'll be able to:
📚 Additional Resources:
Firebase Studio provides a powerful interface for testing and debugging your Genkit applications.
📚 Additional Resources:
Error: Failed to authenticate with Google AI
GOOGLE_GENAI_API_KEY is set correctlyError: Output doesn't match expected schema
Error: Rate limit exceeded
📚 Additional Resources:
Congratulations! You've learned the fundamentals of Firebase Genkit with TypeScript. Here's what you can explore next:
📚 Additional Resources:
Issue: "Module not found" errors
npm install --save-dev @types/node
npm install dotenv
Issue: TypeScript compilation errors
npx tsc --noEmit # Check for type errors
Issue: "tsx command not found"
npm install -g tsx # Install tsx globally, or use npx tsx
Issue: Firebase Studio not starting
npx genkit start --port 4000 # Try different port
Issue: API rate limits
📚 Additional Resources:
You've successfully built three different patterns for working with Firebase Genkit:
These patterns form the foundation for building sophisticated AI-powered applications. Start with simple use cases and gradually build more complex workflows as you become comfortable with the framework.
📚 Continue Your Journey:
Happy building with Firebase Genkit! 🚀