Gofra is an opinionated Go framework aimed at the same general problem space as Rails, Laravel, and Phoenix, but with an API-first architecture built around Go, Connect RPC, Restate, PostgreSQL, and a default SPA frontend.
The repo is still early. The three surfaces that matter are:
- the
gofraCLI for project bootstrap and generators - reusable framework code under
runtime/, such asruntime/config/ - the canonical starter that
gofra newcopies into new applications
The current generator contract is deliberately small:
gofra newcopies a full runnable starter frominternal/scaffold/starter/full/- the generated app imports framework packages from this repo as a library
- app-owned files such as
cmd/app,config/,proto/,gen/, andweb/are created in the generated project - the generated app reserves
public.*for browser-safe runtime config values derived fromproto/<app>/runtime/v1/runtime_config.proto - the generated app currently uses a local
replacedirective back to the framework checkout that created it because the framework module is not published yet
This is the current ownership split:
- CLI-owned: developer tooling and app generators
- framework-owned: reusable behavior that generated apps import
- starter-owned: the canonical generated app layout and placeholder files that
gofra newcopies today - future generated files: app-local code that later generators will rewrite or replace once more of the framework is implemented
The intended runtime-config DX is:
- add a field to
runtime_config.proto - set the value under
public.*in YAML, env, or flags - regenerate and consume the typed field on the frontend
Install the pinned Go toolchain with mise:
mise trust
mise installRun the framework tests:
mise run testGenerate a new app from the canonical starter:
mise run new -- ../myappGenerate a new app with an explicit module path:
mise run new:module -- ../myapp example.com/myappRun the starter smoke test end to end:
mise run smoke:newThat task generates a temporary app and runs go test ./... inside it.
If this is your first time using mise in this checkout, run mise trust
once before invoking mise run ....
These tasks exist in the repo today:
mise run testrunsgo test ./...for the framework repomise run gofrashows the currentgofraCLI helpmise run gen:configshows the config generator helpmise run new -- <path>creates a new app from the canonical startermise run new:module -- <path> <module>creates a new app with an explicit module pathmise run smoke:newverifies that starter generation produces a buildable app
You can also run the underlying commands directly:
go run ./cmd/gofra --help
go run ./cmd/gofra new ../myapp
go run ./cmd/gofra generate config -h
go test ./...The important directories right now are:
cmd/gofra/: the public CLI entrypointinternal/scaffold/: starter copy logic and generation testsinternal/scaffold/starter/full/: the canonical generated-app source treeruntime/config/: reusable config loading and public runtime-config handlerruntime/health/: HTTP health check probes (startup, liveness, readiness)runtime/serve/: HTTP server lifecycle with graceful shutdowninternal/generate/config/: the config code generator internalsdocs/: the architecture and product contract
The intended long-term organization is:
- one public CLI under
cmd/gofra/ - private scaffold and generator internals under
internal/ - public app-facing runtime packages under a stable prefix instead of indefinite flat root-package growth
Start with these docs: