Skip to main content
For the complete documentation index optimized for AI agents, see llms.txt.
Queries for HelixDB can be authored directly in Go with the github.com/helixdb/helix-db/sdks/go module. The Go SDK is dynamic-first: write ordinary Go functions that return helix.Request, declare parameters inline, and execute with client.Exec(ctx, request, &out). There is no bundle-generation step in the primary Go workflow. For the traversal model and query patterns themselves, see Querying and the Querying Guide.

Prerequisites

  • Go 1.22 or later.
  • Optional: the Helix CLI for local development and ad-hoc query testing.

Create a project

mkdir helix-go-app
cd helix-go-app
go mod init example.com/helix-go-app

Add the dependency

go get github.com/helixdb/helix-db/sdks/go
Import the SDK as helix:
import helix "github.com/helixdb/helix-db/sdks/go"

Write query functions

Go queries are normal functions. Use helix.ReadQuery("name") or helix.WriteQuery("name") to set the dynamic request’s query_name, then declare runtime parameters inline with methods such as q.ParamString, q.ParamI64, and q.ParamDateTime.
package users

import helix "github.com/helixdb/helix-db/sdks/go"

type UserRow struct {
	ID       int64  `json:"$id"`
	Name     string `json:"name"`
	TenantID string `json:"tenantId"`
}

type FindUsersResponse struct {
	Users []UserRow `json:"users"`
}

func FindUsers(tenantID string, limit int64) helix.Request {
	q := helix.ReadQuery("find_users")

	tenant := q.ParamString("tenant_id", tenantID)
	maxRows := q.ParamI64("limit", limit)

	return q.
		VarAs("users",
			helix.G().
				NWithLabel("User").
				Where(helix.PredEq("tenantId", tenant)).
				Limit(maxRows).
				ValueMap("$id", "name", "tenantId"),
		).
		Returning("users")
}
Parameter refs can be passed directly into predicates, stream bounds, and mutation property inputs. The SDK inserts both parameters and parameter_types into the dynamic envelope.

Execute queries

package users

import (
	"context"

	helix "github.com/helixdb/helix-db/sdks/go"
)

func ListUsers(ctx context.Context, client *helix.Client, tenantID string, limit int64) (FindUsersResponse, error) {
	var out FindUsersResponse
	err := client.Exec(ctx, FindUsers(tenantID, limit), &out)
	return out, err
}
Create the client once and reuse it:
client, err := helix.NewClient("https://helix.example.com", helix.WithAPIKey("hx_secret"))
if err != nil {
	return err
}

var out FindUsersResponse
err = client.Exec(ctx, FindUsers("acme", 25), &out)
For local development, pass "" or "http://localhost:6969" to NewClient.

Write queries

type CreateUserResponse struct {
	User []UserRow `json:"user"`
}

func CreateUser(name string, tenantID string) helix.Request {
	q := helix.WriteQuery("create_user")

	nameParam := q.ParamString("name", name)
	tenant := q.ParamString("tenant_id", tenantID)

	return q.
		VarAs("user",
			helix.G().AddN("User", helix.Props{
				helix.Prop("name", nameParam),
				helix.Prop("tenantId", tenant),
			}),
		).
		Returning("user")
}
Use execution options when a write must hit the writer node or wait for durability:
var created CreateUserResponse
err = client.Exec(ctx, CreateUser("Alice", "acme"), &created,
	helix.WriterOnly(),
	helix.AwaitDurability(true),
)

Next Steps

Querying

Dynamic query envelopes, client execution, and transactions.

Parameters & bundles

Parameter serialization across TypeScript, Rust, and Go.

Local Development

Run HelixDB locally while developing queries.

Go SDK source

Go module source and README.