dreego — Go Web Framework
SSR-first web framework and evolving Go-native application platform. Write
.dreego files, transpile to Go code, and deploy the current SSR target as a
single binary. File-based routing, built-in form handling, and compile-time
validation work without runtime template parsing.
<!-- www/routes/login/post.dreego -->
<head><title>Dreego</title></head>
<server>
type LoginForm struct {
Email string `form:"email" validate:"required,email"`
}
func Login(c dreego.Context, form LoginForm) error {
c.SetSessionVal("user", form.Email)
return c.Redirect("/dashboard", 303)
}
</server>
<body>
<h1>Login</h1>
{#if c.Errors("email")}<p class="error">{{ c.Errors("email") }}</p>{/if}
<form g-action="Login" method="post">
<input name="email" type="email" value="{{ c.Old("email") }}">
<button type="submit">Login</button>
</form>
</body>
dreego new myapp && cd myapp && dreego generate && go run .
→ Getting Started
Philosophy
Dreego is a compile-time transpiler, not a runtime framework. .dreego files compile to standard Go code — no reflection-based routers, no runtime template parsing. Your app is a plain Go binary using net/http. See Benchmarks for measured code-generation and request performance.
Four principles:
- SSR-First — SSR is the production web foundation. Target-neutral
rendering supports a planned Wails host, while DreeJS adds optional browser
and WebView behavior.
- File-Based —
www/routes/page.dreego maps to GET /. One route file per URL with method-specific sections. Legacy names get.dreego, index.dreego, and +page.dreego remain accepted.
- Type-Safe — Generated handlers and components use typed Go contracts; dynamic HTTP boundary data stays explicit.
- Accessibility-Aware Tooling — CLI output and diagnostics are designed for screen readers, and the landing blueprint demonstrates semantic navigation. Applications still verify their own content and conformance.
Direction after v0.1
Dreego is intended to let one typed application and component model serve
multiple explicit first-party targets:
target-neutral App + renderer
├── target/ssr
└── target/wails
optional browser behavior
└── DreeJS: local, fetch, poll, stream, live
Root sections describe purpose while an optional lang selects the source
processor: server, head, body, style, and client. Go, HTML, CSS, and
JavaScript are the built-in defaults.
Static components produce no DreeJS runtime. Components that request browser
behavior receive only the modules they use. JavaScript remains the built-in,
dependency-free client language. Markdown and TypeScript are first-party
processors. Browser Lua compiles through Dreego's dependency-free first-party
compiler and a generated feature-linked runtime.
See the public Roadmap, detailed
implementation plans, and accepted
target architecture decision.
Features
Core
- Transpiler Pipeline — Lexer → Parser → AST → CodeGen.
.dreego → Go code.
- File-based Routing —
www/routes/page.dreego → GET /, www/routes/login/page.dreego → GET /login (method via method="..." sections)
- Dynamic Segments —
[id] brackets for URL params, (group)/ for layout groups
- Single Binary —
go build → deploy one file. Zero runtime dependencies beyond net/http.
Template & Components
- Template Logic —
{{ value }}, {#if}...{#else}...{/if}, {#each items as item}...{#each else}...{/each}
- Template Helpers —
{{ $loop.Index }}, {{ value|raw }}, {{ value|upper }}, {#verbatim}
- Component System —
www/components/, <@Card title="x">...<\@Card>, named slots, scoped CSS
- Layout System —
www/layouts/default.dreego with {#slot} + {#head}
- CSS Scoping —
data-scope via source hash, automatically applied
- g-action Forms —
<form g-action="Login"> generates full handler pipeline
- Auto-Validation —
validate:"required,email,min=3" struct tags, no external deps
- Auto-Binding —
form:"email" struct tags → r.ParseForm() + reflection mapping
- Error Re-render —
c.Errors("email") and c.Old("email") available in templates after validation failure
- PRG Pattern —
c.Redirect(url, 303) with ErrRedirect sentinel for after-success redirect
API Endpoints (v0.0.15)
- Content-Type Routing —
<server type="json">, <server type="xml">, <server type="custom">
- JSON API —
c.JSON(200, data), c.Bind(&target), auto Content-Type: application/json
- XML API —
c.XML(200, data), auto Content-Type: application/xml
- Custom —
c.Write(status, contentType, body) for arbitrary formats
Middleware (v0.0.14, v0.0.20)
- Health Checks —
GET /health → 200, GET /ready → 200/503 via app.SetReady(bool)
- Security Headers — X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Content-Security-Policy (configure via
app.SetCSP before build)
- Gzip Compression —
Accept-Encoding → compressed response wrapping
- Recovery — Panic → 500 with stack trace
- Request Logging — JSONL format with duration, IP, status
- Session — Cookie store via
app.SetSessionStore(), c.SetSessionVal()
- CSRF — Double-submit cookie, auto-validation on POST/PUT/DELETE, Secure flag TLS-aware
Developer Experience
- CLI —
dreego init, dreego generate [--force] [--check], dreego fmt [--check]
- CI Mode —
dreego generate --check exits non-zero when generated files are stale
- Auto-Imports —
fmt, html, strings, net/http added to generated code as needed
- Accessibility Checks —
dreego generate warns about missing image alternatives and unassociated form labels; CLI output is color-free and screen-reader-linear
Quick Start
Requires Go 1.22 or newer (go version). The dreego new command scaffolds a
project, writes a go.mod that requires the published dreego module, and
runs go mod tidy so the build resolves from the public Go proxy. No
repository-local replace directive is needed for a release-installed CLI.
# 1. Install the Dreego CLI
go install github.com/dreego-stack/dreego/cli/dreego@latest
# 2. Scaffold a new project (writes go.mod, main.go, www/ tree, runs go mod tidy)
dreego new myapp
# 3. Generate Go code from .dreego files and run the server
cd myapp
dreego generate
go run .
# → http://localhost:8080
# or build for production
dreego build --target linux/amd64
docker build -t myapp .
main.go uses the explicit App API — no globals, no hidden state:
package main
import (
"log"
dreego "github.com/dreego-stack/dreego/core"
"github.com/dreego-stack/dreego/core/ssr"
"myapp/www"
)
func main() {
app := dreego.New()
if err := www.Register(app); err != nil {
log.Fatal(err)
}
if err := ssr.Listen(app, ":8080"); err != nil {
log.Fatal(err)
}
}
If dreego new cannot resolve the dreego dependency (e.g. no network, or the
CLI was built from an untagged checkout), set DREEGO_LOCAL_REPO=/path/to/dreego
to point the scaffold at a local checkout via a replace directive. This is a
developer escape hatch and is not part of the canonical path.
VS Code Extension
Syntax highlighting, snippets, and dreego.config.json validation for
.dreego files. Install via a symlinked clone — always up to date:
git clone --depth 1 https://github.com/dreego-stack/vscode-dreego ~/dev/vscode-dreego
cd ~/dev/vscode-dreego
./install.sh
Restart VS Code afterwards. Uninstall: ./install.sh uninstall in the same
directory. The install script links ~/.vscode/extensions/dreego to the
checkout, so use a permanent directory (not /tmp, which is cleared on
reboot). Source: https://github.com/dreego-stack/vscode-dreego
Architecture
A website lives in its own directory — any name, marked by a
dreego.config.json. dreego generate produces one dree.go per directory
with .dreego sources; the website root gets a Register(app) entry point:
www/ # website root (name is free, marker: dreego.config.json)
├── dreego.config.json # logging, redirects, rewrites
├── dree.go # GENERATED — package www, Register(app)
├── routes/ # .dreego files → URL routes
│ ├── page.dreego → GET /
│ ├── login/
│ │ └── page.dreego → GET /login (POST via method="post" section)
│ ├── [id]/page.dreego → GET /{id}
│ └── dree.go # GENERATED — package routes, handlers + Register
├── layouts/
│ ├── default.dreego # {#slot} + {#head} wrapper
│ └── dree.go # GENERATED — package layouts
├── components/
│ ├── Card.dreego # <@Card title="x"/>
│ └── dree.go # GENERATED — package components
├── static/
│ └── style.css # inlined into binary
└── main.go # imports "myapp/www", calls www.Register(app)
Multiple websites can share one module — each directory with a
dreego.config.json is an independent website.
Plugins
Official plugins live in separate repos under github.com/dreego-stack/. Each plugin has its own go.mod and requires github.com/dreego-stack/dreego; Core stays dependency-free and never imports a plugin package.
Provider integrations such as Stripe, MapLibre, auth, storage, Tailwind, SSE,
and WebSockets remain external. The small first-party language set—Markdown,
TypeScript, and Lua—stays in the transpiler and may manage pinned tools after
explicit approval. SSR, Wails, and DreeJS stay in the monorepo because they
share the compiler and rendering contracts.
github.com/dreego-stack/
├── dreego/ # main repo (core + CLI, single module)
├── plugin-example/ # minimal example plugin
├── plugin-auth/ # future: OAuth2, JWT, sessions
├── plugin-db/ # future: SQL drivers, migrations
└── ...
→ Plugin System
Documentation
Getting Started
| Doc |
Topic |
_docs/index.md |
Documentation index and navigation |
_docs/getting-started.md |
Step-by-step tutorial |
_docs/cli.md |
CLI Reference |
_docs/config.md |
dreego.config.json |
Guides
| Doc |
Topic |
_docs/routing.md |
File-based routing, dynamic segments, content-type routing |
_docs/layouts.md |
Layouts, {#slot} and {#head} |
_docs/middleware.md |
Health, security, compression, session, CSRF |
_docs/components.md |
Component system, slots, scoped CSS |
_docs/forms.md |
g-action forms, validation, redirects, error handling |
_docs/session-encryption.md |
AES-256-GCM encrypted session cookies |
_docs/progressive-enhancement.md |
HTMX, Alpine.js, plain JavaScript |
_docs/security.md |
Context-aware escaping, output safety |
_docs/accessibility.md |
Accessibility guarantees and blueprint defaults |
Reference
| Doc |
Topic |
_docs/runtime.md |
Practical guide to the main Go runtime APIs |
_docs/plugin-interfaces.md |
Plugin interface contracts |
_docs/plugins.md |
Plugin model, middleware and route hooks |
_docs/compatibility.md |
Breaking-change policy and the v0.1 promise |
_docs/roadmap.md |
Product direction and release phases |
_plan/README.md |
Detailed phased architecture and implementation guidance |
Testing & Ops
| Doc |
Topic |
_docs/testing.md |
Integration test strategy |
_docs/benchmarks.md |
Code generation and request benchmarks |
_docs/reference-apps.md |
Reference applications under _tests/fixtures/ |
_docs/dev-server.md |
dreego dev watcher and auto-reload |
_docs/hot-reload.md |
Hot reload with Air (.air.toml config) |
_docs/deployment.md |
Build, cross-compile, containers |
Contributing
See CONTRIBUTING.md for the PR workflow, commit
conventions, and local development setup.
License
MPL-2.0