Skip to main content
This guide will help you create your first AI-powered application using Genkit for Go. You’ll learn how to initialize Genkit, make your first generation request, and work with structured data.

Prerequisites

Step 1: Initialize Your Project

Create a new Go module:
mkdir my-genkit-app
cd my-genkit-app
go mod init my-genkit-app

Step 2: Install Genkit

Add Genkit and the Google AI plugin to your project:
go get github.com/firebase/genkit/go
go get github.com/firebase/genkit/go/plugins/googlegenai

Step 3: Set Your API Key

Set your Google AI API key as an environment variable:
export GEMINI_API_KEY="your-api-key-here"

Step 4: Create Your First Application

Create a file named main.go:
main.go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/firebase/genkit/go/ai"
    "github.com/firebase/genkit/go/genkit"
    "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
    ctx := context.Background()
    g := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}))

    answer, err := genkit.GenerateText(ctx, g,
        ai.WithModelName("googleai/gemini-2.0-flash"),
        ai.WithPrompt("Why is Go a great language for AI applications?"),
    )
    if err != nil {
        log.Fatalf("could not generate: %s", err)
    }
    fmt.Println(answer)
}

Step 5: Run Your Application

Run your application with the Genkit CLI for automatic tracing:
genkit start -- go run main.go
Or run it directly:
go run main.go
You should see a response explaining why Go is great for AI applications.

Access the Developer UI

When running with genkit start, open http://localhost:4000 to access the Developer UI where you can:
  • View execution traces
  • Test flows interactively
  • Debug multi-step operations

Generate Structured Data

Genkit for Go provides type-safe JSON output with GenerateData:
type Recipe struct {
    Title       string   `json:"title"`
    Ingredients []string `json:"ingredients"`
    Steps       []string `json:"steps"`
}

recipe, err := genkit.GenerateData[Recipe](ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithPrompt("Create a recipe for chocolate chip cookies."),
)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Recipe: %s\n", recipe.Title)
fmt.Printf("Ingredients: %v\n", recipe.Ingredients)

Stream Responses

Stream text as it’s generated for responsive user experiences:
stream := genkit.GenerateStream(ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithPrompt("Write a short story about a robot learning to paint."),
)

for result, err := range stream {
    if err != nil {
        log.Fatal(err)
    }
    if result.Done {
        break
    }
    fmt.Print(result.Chunk.Text())
}

Define Tools

Give models the ability to take actions and access external data:
type WeatherInput struct {
    Location string `json:"location"`
}

weatherTool := genkit.DefineTool(g, "getWeather",
    "Gets the current weather for a location",
    func(ctx *ai.ToolContext, input WeatherInput) (string, error) {
        // Call your weather API here
        return fmt.Sprintf("Weather in %s: 72°F and sunny", input.Location), nil
    },
)

response, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithPrompt("What's the weather like in San Francisco?"),
    ai.WithTools(weatherTool),
)
if err != nil {
    log.Fatal(err)
}
fmt.Println(response.Text())

Create a Flow

Flows wrap your AI logic for better observability and deployment:
jokeFlow := genkit.DefineFlow(g, "tellJoke",
    func(ctx context.Context, topic string) (string, error) {
        return genkit.GenerateText(ctx, g,
            ai.WithModelName("googleai/gemini-2.0-flash"),
            ai.WithPrompt(fmt.Sprintf("Tell me a joke about %s", topic)),
        )
    },
)

joke, err := jokeFlow.Run(ctx, "programming")
if err != nil {
    log.Fatal(err)
}
fmt.Println(joke)

Define Prompts

Create reusable prompts with Handlebars templating:
greetingPrompt := genkit.DefinePrompt(g, "greeting",
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithPrompt("Write a {{style}} greeting for {{name}}."),
)

response, err := greetingPrompt.Execute(ctx, ai.WithInput(map[string]any{
    "name":  "Alice",
    "style": "formal",
}))
if err != nil {
    log.Fatal(err)
}
fmt.Println(response.Text())

Expose Flows as HTTP Endpoints

Serve your flows over HTTP with automatic JSON serialization:
import (
    "log"
    "net/http"
)

mux := http.NewServeMux()
for _, flow := range genkit.ListFlows(g) {
    mux.HandleFunc("POST /"+flow.Name(), genkit.Handler(flow))
}
log.Fatal(http.ListenAndServe(":8080", mux))
Test your endpoint:
curl -X POST http://localhost:8080/tellJoke \
  -H "Content-Type: application/json" \
  -d '{"data": "programming"}'

Try Other Model Providers

Genkit supports multiple AI providers:
import (
    "github.com/firebase/genkit/go/plugins/anthropic"
    "github.com/firebase/genkit/go/plugins/ollama"
)

g := genkit.Init(ctx, genkit.WithPlugins(
    &googlegenai.GoogleAI{},
    &anthropic.Anthropic{},
    &ollama.Ollama{
        ServerAddress: "http://localhost:11434",
    },
))

// Use Claude
response, _ := genkit.Generate(ctx, g,
    ai.WithModelName("anthropic/claude-3-5-sonnet-20241022"),
    ai.WithPrompt("Hello, Claude!"),
)

// Use local Ollama models
response, _ = genkit.Generate(ctx, g,
    ai.WithModelName("ollama/llama2"),
    ai.WithPrompt("Hello, Llama!"),
)

Learn More

Go API Reference

Explore the complete Go API

Structured Output

Generate type-safe JSON responses

Tool Calling

Give AI models access to functions

Deployment

Deploy your Go applications

Build docs developers (and LLMs) love