CARLOS rastrillo

Fast, cost-efficient, good: pick all three with rastrillo.

The web framework companion to CARLOS: declare what your app is, read every line it generates, and ship it to a platform that only bills you when someone shows up.

The opening statement: what you write against what rastrillo generates
declared, in manifest/ticket_types.toml15 lines
generated, under gen/ โ€” plain Go, SQL, HTML1,978 lines
parsed behind your back at request time0
Try it now Read the source

๐Ÿค– This page was written by an LLM, on the ideas, instruction, and editing of humans. AI-written text here is always marked, visibly, like this โ€” that's factor X.

Fifteen lines in. An admin you can read, out.

Generated, not interpreted โ€” everything it writes, you can read.

declared manifest/ticket_types.toml โ€” the whole file
name  = "ticket_types"route = "/admin/ticket_types"store = "exclusive"[list]columns = [{ field = "Name" }, { field = "Price", kind = "money" }, { field = "Status" }]search  = true[[list.filters]]field  = "Status"values = ["draft", "on_sale", "sold_out"][form]basics   = [{ name = "Name", required = true }, { name = "Price", kind = "money", required = true }, { name = "Status" }]advanced = [{ name = "MaxPerOrder" }]
generated what rastrillo generate wrote from it
files committed under gen/, diffable in review like any code21
lines of plain Go, SQL, HTML, and locale keys1,978
actions, wired into the router โ€” list, create, show, edit7
screens โ€” a list with search, a working Status filter and paging; a two-tier form; a show page3
typed store โ€” schema, additive migrations, sqlc queries1
TOML parsed at request time0

required = true is server-side: the generated actions 400 with the field's own message, re-rendered in the form. There is no actions/ directory in this app at all โ€” examples/tickets is manifest-only, and it's the framework's own regression suite. And when a generated screen stops being enough, eject it: the file becomes yours, and the generator leaves it alone.

Boring machinery, deliberately

Go's standard library, SQLite, and files you can read โ€” nothing decided 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, and rastrillo generate writes it all into a plain gen/router.go on Go's standard http.ServeMux: committed, readable, diffable.
Platform-ready by default
rastrillo.Run speaks the CARLOS platform's activation contract end to end โ€” hibernating instances, carlos-app@ systemd unit tenants, plain instances, and a bare dev fallback, no separate integration per deployment shape. Hibernation is the cost-efficiency receipt: your app isn't running when nobody's knocking, and the platform wakes it when someone does.
Localization built in
Declare your locales and /fr/orders and /orders reach the same route. Request-scoped T/Tf fall back through catalogs so a missing translation stays visible, never blank โ€” and generate --check fails loudly on incomplete catalogs before you ship, not after.
A UI vocabulary, zero JavaScript
rastrillo/ui ships list-screen and form partials plus design tokens: light and dark, WCAG AA contrast, and not one line of client-side JavaScript. examples/blog is a real blog, admin side and all, from stock components only.
One binary, no toolchain sprawl
go install gets you the CLI, go build gets you the app โ€” a single static binary with SQLite compiled in. No bundler, no separate codegen service, no runtime to babysit. The framework whose family motto is "no build step" doesn't ship one to your visitors either.

Deployedlive ยท real edge

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 two minutes from now, actually shipped. This site is served the same way.

Run it locally

One command to install, three more to a running app.

1

Install the CLI

go install github.com/carlosframework/rastrillo/cmd/rastrillo@latest

Or via Homebrew: brew install carlosframework/tap/rastrillo.

2

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 โ€” then runs generate once, so the next step just works.

3

Run it

cd myapp && go get github.com/carlosframework/rastrillo@latest && rastrillo dev

Visit localhost:8080 โ€” that's your app. Edit an action, save, 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.

1

Install the platform binary

brew install carlosframework/tap/carlos

Or grab a binary directly from carlosframework/releases.

2

Build your app for the target host

GOOS=linux GOARCH=arm64 go build -o myapp-binary ./cmd/myapp
3

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

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 is the one-off part; from then on every deploy is ship then promote.

What's real today

A young framework that ships its status on its homepage โ€” this list moves when the work lands, not before.

Posted

  • rastrillo new / generate โ€” scaffold and route
  • rastrillo dev โ€” save, and it regenerates, rebuilds, restarts
  • Manifests: a declared Resource generates store, actions, screens, and locale keys โ€” with declared filters and server-side required validation
  • examples/tickets โ€” a fully generated admin: zero hand actions, zero ejected templates
  • rastrillo.Run โ€” the full platform activation contract, hibernate and systemd tenants included
  • SQLite bootstrap: pragma ordering, single-writer, additive migrations
  • Localization: locale-resolved routes, T/Tf with fallback, a ship-gate catalog check
  • rastrillo/ui โ€” list-screen and form partials plus design tokens: light and dark, WCAG AA, zero JavaScript
  • examples/blog โ€” a real blog from stock components, coexisting with hand-written actions

Pending

  • The mergeable event-log store, blobs
  • The crypto core, WebAuthn
  • Agents
  • The rest of the component vocabulary โ€” and the rest of the manifest surface (delete flows, derived fields, richer kinds)