Structure, not a runtime to trust
Everything rastrillo generates, you can read — because it's a file, not a request handled behind your back.
Filesystem routing
actions/orders/[id]/cancel.POST.go becomes POST /orders/{id}/cancel — the directory structure is the route table. Bracket segments are path params, the filename suffix is the HTTP verb.
Generated, not interpreted
rastrillo generate writes a plain gen/router.go on Go's standard http.ServeMux — committed, readable, diffable. Nothing is decided by parsing a manifest at request time.
Platform-ready by default
rastrillo.Run already speaks the CARLOS platform's activation contract end to end — hibernating instances, carlos-app@ systemd unit tenants, plain instances, and a bare dev fallback all handled, no separate integration per deployment shape — plus the SQLite pragma-ordering fix and additive migrations.
One binary, zero build step beyond Go
No bundler, no separate codegen toolchain to install — go install gets you the CLI, go build gets you the app. The framework whose homepage brags about no build step doesn't get to ship one on its own tools either.
What's real today
A v1 walking skeleton, built to prove the core loop end to end — not the full design yet.
Built
rastrillo new/generate— scaffold and routerastrillo dev— save, and it regenerates, rebuilds, restartsrastrillo.Run— the full platform activation contract, hibernate and systemd tenants included- SQLite bootstrap: pragma ordering, single-writer, additive migrations
- Localization: locale-resolved routes,
T/Tfwith fallback, a ship-gate catalog check rastrillo/ui— eight List-screen partials plus design tokens: light and dark, WCAG AA contrast, zero JavaScriptexamples/blog— a real blog, admin side and all, from stock components only- A real example, deployed for real — see below
Not yet
- The typed-manifest / TOML component system
- The mergeable event-log store, blobs
- The crypto core, WebAuthn
- Agents, the rest of the component vocabulary beyond List screens
Live proof
Not a mockup
Rastrillo's example app is deployed on a real CARLOS platform right now: real S3-backed storage, a real edge, a real certificate. helloworld.dev.oncarlos.com — the exact code you'll have running locally in the next section, actually shipped.
Run it locally
One command to install, three more to a running app.
Install the CLI
go install github.com/carlosframework/rastrillo/cmd/rastrillo@latest
Or via Homebrew: brew install carlosframework/tap/rastrillo.
Scaffold an app
rastrillo new myapp
Writes a go.mod, one starter action, a main.go wiring rastrillo.Run, and the rastrillo/ui design tokens as static/tokens.css — then runs generate once, so the next step just works.
Run it
cd myapp && go mod tidy && rastrillo dev
Visit localhost:8080 — that's your app, served by rastrillo.Run. Now edit an action, save, and refresh: rastrillo dev regenerates, rebuilds, and restarts for you, in about a second. A save that doesn't compile keeps the previous build serving while you fix it.
Deploy it for real
CARLOS is self-hostable — one binary, a bucket, and DNS. No PaaS account to sign up for.
Install the platform binary
brew install carlosframework/tap/carlos
Or grab a binary directly from carlosframework/releases.
Build your app for the target host
GOOS=linux GOARCH=arm64 go build -o myapp ./cmd/myapp
Ship, promote, route
carlos ship -app myapp -version $(git rev-parse --short HEAD) myapp-binary
carlos promote -app myapp <version> stable
carlos add -app myapp -kind instance myapp.yourdomain.com
That's the same sequence — against a real S3-backed bucket, a real edge, a real certificate — that put rastrillo's own example live at helloworld.dev.oncarlos.com. Standing up the box, bucket, and DNS the first time is the one-off part; from here on, every deploy is ship then promote.