Skip to content

tinywasm/goflare

Repository files navigation

GoFlare

GoFlare is a self-contained Go tool (library + CLI) for deploying Go WASM projects to Cloudflare Workers and Pages. No Node.js, no Wrangler, no GitHub Actions. Pure Go, direct Cloudflare API.

When to use

  • Deploying Cloudflare Workers written in Go (WASM)
  • Deploying Cloudflare Pages (Static sites or Go WASM frontends)
  • Full-stack Go WASM projects (Frontend + Edge Backend)

Project layout (canonical)

The following structure is recommended and auto-detected by GoFlare:

my-project/
├── .env                 # credentials — gitignored
├── .env.example         # public template
├── modules/
│   └── contact/
│       ├── model.go       # shared models — build-agnostic
│       └── model_orm.go   # generated by ormc
├── web/
│   ├── client.go          # //go:build wasm — frontend (browser)
│   ├── server.go          # //go:build !wasm — local dev server
│   └── public/            # PUBLIC_DIR — deployed as-is to Cloudflare Pages
│       ├── index.html
│       ├── client.wasm    # generated by goflare build
│       ├── script.js      # generated by goflare build
│       └── style.css      # generated by goflare build
├── edge/
│   └── main.go            # //go:build wasm — edge function (Cloudflare Worker)
│                          # auto-detected: no ENTRY= in .env needed
└── .build/                # OutputDir — gitignored, worker artifacts only
    ├── edge.js
    └── edge.wasm

.env

Create a .env file in your project root:

PROJECT_NAME=my-app
CLOUDFLARE_ACCOUNT_ID=your-account-id
PUBLIC_DIR=web/public
# ENTRY=edge  # Optional: auto-detected if edge/main.go exists
# DOMAIN=example.com  # Optional: custom domain for Pages

CLI

Install the CLI:

go install github.com/tinywasm/goflare/cmd/goflare@latest
  • goflare init: Setup project and .env
  • goflare build: Compile WASM and generate assets
  • goflare deploy: Deploy to Cloudflare

Edge function (worker/backend)

Minimal working edge/main.go using workers.Handle:

//go:build wasm

package main

import "github.com/tinywasm/goflare/workers"

func main() { workers.Handle(handler) }

func handler(w *workers.Response, r *workers.Request) {
    w.Header()["Content-Type"] = "application/json"
    w.WriteHeader(200)
    w.Write([]byte(`{"ok":true}`))
}

Note: auto-detected, no ENTRY= needed if using the edge/ directory.

Frontend WASM

Minimal working web/client.go:

//go:build wasm

package main

import (
    "github.com/tinywasm/dom"
    "github.com/tinywasm/form"
)

type MyForm struct {
    Name string `input:"required"`
}

func main() {
    data := &MyForm{}
    f, _ := form.New("app", data)
    dom.Render("app", f)
    select {}
}

Note: compiled to web/public/client.wasm.

Shared models (modules/)

Shared models live in modules/ and can be imported by both frontend and edge.

package contact

// ormc:formonly
type ContactForm struct {
    Nombre  string `input:"required,min=2"`
    Email   string `input:"email,required"`
    Mensaje string `input:"textarea,required,min=10"`
}

Library usage

cfg := &goflare.Config{
    ProjectName: "myapp",
    AccountID:   "acc-id",
    PublicDir:   "web/public",
}
g := goflare.New(cfg)
g.Build()
store := goflare.NewKeyringStore()
g.Deploy(store)

Config reference

Field .env key Default Notes
ProjectName PROJECT_NAME required
AccountID CLOUDFLARE_ACCOUNT_ID required
WorkerName WORKER_NAME <ProjectName>-worker optional
Entry ENTRY auto: edge if edge/main.go exists directory name, not a file
PublicDir PUBLIC_DIR required for Pages deploy
Domain DOMAIN optional custom domain
CompilerMode COMPILER_MODE S S=small/prod, M=debug, L=Go std

At least one of Entry or PublicDir must be set.

Build output

After goflare build:

  • web/public/: Pages source (index.html, client.wasm, script.js, style.css)
  • .build/: Worker artifacts (edge.js, edge.wasm)
  • NO dist/ directory is created.

Compiler modes

  • S: Small (TinyGo production, minified)
  • M: Medium (TinyGo debug)
  • L: Large (Go standard compiler)

Requirements

  • Go 1.25.2+
  • TinyGo — installed automatically by goflare build via tinywasm/tinygo

goflare calls tinygo.EnsureInstalled() before each Worker build. If TinyGo is already in PATH at the correct version, nothing happens. If it is missing or outdated, it is downloaded and installed to the local cache automatically.

To manage TinyGo independently:

import "github.com/tinywasm/tinygo"

tinygo.EnsureInstalled()
env := tinygo.GetEnv()

Reference project

See goflare-demo for a complete example.

About

GoFlare is a lightweight handler for building and deploying Go-based WebAssembly and JavaScript modules to Cloudflare Workers, Pages, or Functions. Designed to integrate seamlessly into existing build pipelines and tools.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors