Go + Temporal + typed generated glue

Typed Temporal workflows in Go, without the boilerplate.

Vihren generates typed activity proxies, workflow clients, and worker registration code for Go projects that use Temporal.

53 lines of workflow source
84 generated lines
0 external site scripts
examples/codegenhello/workflow.go
//go:generate go run ../../cmd/vihren-gen --manifest .cache/codegenhello.manifest.json ./examples/codegenhello

func HelloWorkflow(ctx workflow.Context, input GreetingInput) (GreetingOutput, error) {
	options := workflow.ActivityOptions{StartToCloseTimeout: time.Minute}
	ctx = workflow.WithActivityOptions(ctx, options)

	return Activity.ComposeGreeting(ctx, input)
}

The generated layer removes the repetitive Temporal glue.

Write plain Go workflows and activities, then let the generator produce the typed registration, activity proxy, and client entry points that workers and callers use.

Typed activity proxy

func (activityProxy) ComposeGreeting(ctx workflow.Context, input GreetingInput) (GreetingOutput, error) {
	var result GreetingOutput
	err := workflow.ExecuteActivity(ctx, ComposeGreetingActivityName, input).Get(ctx, &result)
	return result, err
}

Typed workflow client

func (c Client) HelloWorkflow(ctx context.Context, options client.StartWorkflowOptions, input GreetingInput) (client.WorkflowRun, error) {
	return c.Client.ExecuteWorkflow(ctx, options, HelloWorkflowName, input)
}

Worker setup gets a single generated registration call.

The example runs against an embedded Temporal server so the workflow path can be exercised locally without a separate service.

1. start

Start embedded Temporal

The local server is process-owned and closes with the example.

2. register

Register generated symbols

Activities and workflows are registered from generated code.

3. call

Use the typed client

Workflow calls use generated names and Go input types.

Generated registration

func Register(r interface {
	RegisterActivityWithOptions(a any, options activity.RegisterOptions)
	RegisterWorkflowWithOptions(w any, options workflow.RegisterOptions)
}) {
	RegisterActivities(r)
	RegisterWorkflows(r)
}

Embedded server

server, err := embeddedtemporal.Start()
if err != nil {
	return err
}
defer server.Close()

Run the codegen hello example.

The v0.1 path is intentionally small: install the module, run the embedded Temporal example, and inspect the generated file.

shell
go get github.com/vihren-dev/vihren
go install github.com/vihren-dev/vihren/cmd/vihren-gen@latest

go run ./examples/codegenhello/cmd/codegenhello-embedded

Hello, Ada

Blog

Launch notes and engineering writeups for the public Vihren surface, starting with the hello-world launch note.

Hello world: Vihren v0.1.0

Typed Temporal code generation, the runnable codegenhello example, and embedded Temporal for local development.

v0.1 is a project preview.

No hosted service, no signup flow, and no product claims beyond the code that ships in the public repository.

Open pkg.go.dev