Skip to navigation

To set up BAML with Go do the following:

1

Install BAML VSCode/Cursor Extension

https://marketplace.visualstudio.com/items?itemName=boundary.baml-extension

  • syntax highlighting
  • testing playground
  • prompt previews
2

Install BAML CLI and Initialize Project

go
go install github.com/boundaryml/baml/baml-cli@latest && baml-cli init

This command will:

  1. Install the BAML CLI tool globally
  2. Create starter BAML code in a baml_src directory
  3. Set up the basic project structure
3

Install BAML Go Runtime

After initializing your project, install the Go runtime library:

go
go get github.com/boundaryml/baml
4

Install Required Go Tools

The BAML generator uses gofmt and goimports to format the generated Go code. Install these tools:

go
# gofmt comes with Go by default, but install goimports
go install golang.org/x/tools/cmd/goimports@latest

These tools are required by the on_generate command in your generator configuration and ensure the generated code is properly formatted.

5

Generate the baml_client Go package from .baml files

One of the files in your baml_src directory will have a generator block. This tells BAML how to generate the baml_client directory, which will have auto-generated Go code to call your BAML functions.

Any types defined in .baml files will be converted into Go structs in the baml_client directory.

baml-cli generate

You can modify your build process to always call baml-cli generate before building.

Makefile
.PHONY: generate build
generate:
baml-cli generate
build: generate
go build ./...
test: generate
go test ./...

See What is baml_client to learn more about how this works.

If you set up the VSCode extension, it will automatically run baml-cli generate on saving a BAML file.

6

Use a BAML function in Go!

If baml_client doesn’t exist, make sure to run the previous step!
main.go
package main
import (
"context"
"fmt"
"log"
b "example.com/myproject/baml_client"
"example.com/myproject/baml_client/types"
)
func main() {
ctx := context.Background()
// BAML's internal parser guarantees ExtractResume
// to always return a Resume type or an error
resume, err := b.ExtractResume(ctx, rawResume)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Extracted resume: %+v\n", resume)
}
func exampleStream(rawResume string) (*types.Resume, error) {
ctx := context.Background()
stream, err := b.Stream.ExtractResume(ctx, rawResume)
if err != nil {
return nil, err
}
for value := range stream {
if value.IsError {
return nil, value.Error
}
if !value.IsFinal && value.Stream() != nil {
partial := *value.Stream()
fmt.Printf("Partial: %+v\n", partial) // This will be a partial Resume type
}
if value.IsFinal && value.Final() != nil {
final := *value.Final()
return &final, nil // This will be a complete Resume type
}
}
return nil, fmt.Errorf("stream ended without final response")
}

Working with Go Modules

BAML integrates seamlessly with Go modules. Make sure your go.mod file includes the BAML dependency:

go.mod
module example.com/myproject
go 1.21
require (
github.com/boundaryml/baml v0.203.1
)

The generated baml_client package will use your module path, so you can import it as:

import (
b "example.com/myproject/baml_client"
"example.com/myproject/baml_client/types"
)

Context and Cancellation

All BAML Go functions require a context.Context as the first parameter, allowing you to:

// Set timeouts
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
result, err := b.ExtractResume(ctx, resume)
// Handle cancellation
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(5 * time.Second)
cancel() // Cancel the request after 5 seconds
}()
result, err := b.ExtractResume(ctx, resume)
if errors.Is(err, context.Canceled) {
fmt.Println("Request was canceled")
}

You’re all set! Continue on to the Deployment Guides for your language to learn how to deploy your BAML code or check out the Interactive Examples to see more examples.