A convention-first web framework for Gleam.
Productive like Phoenix, explicit like Gleam, composable with Wisp and Lustre.
Tutorial · Documentation · CLI Reference · Hex Package · Contributing
Light enters a prism, structure emerges. Refrakt takes the Gleam ecosystem — Wisp, Lustre, Mist — and gives you one obvious way to build serious web apps. No macros. No magic. Just conventions, generators, and plain Gleam code you own.
One command, full CRUD. refrakt gen resource posts title:string body:text published:bool generates a handler with 7 actions, Lustre HTML views, typed form validation, a domain type, database repo with raw SQL, a migration, and tests — then wires all routes into your router automatically.
# Add refrakt to a Gleam project (or use it standalone)
gleam add refrakt
# Create a new project with PostgreSQL
gleam run -m refrakt/cli -- new my_app --db postgres
cd my_app
# Generate a full CRUD resource
gleam run -m refrakt/cli -- gen resource posts title:string body:text published:bool
# Start the server
gleam run
# → http://localhost:4000/postsOr with SQLite — no external database needed:
gleam run -m refrakt/cli -- new my_app --db sqlitemy_app/
src/
my_app.gleam ← entry point (Wisp + Mist)
my_app/
config.gleam ← typed config, env-driven
context.gleam ← shared context (config + db)
router.gleam ← all routes, pattern matched
web/ ← HTTP/UI layer
post_handler.gleam ← 7 CRUD actions
post_views.gleam ← Lustre HTML (type-safe, no templates)
forms/post_form.gleam ← typed decoder + validation
layouts/root_layout.gleam ← HTML shell
middleware/auth.gleam ← session auth (if gen auth)
domain/ ← pure Gleam (zero framework imports)
post.gleam ← pub type Post { Post(...) }
data/ ← persistence
post_repo.gleam ← raw SQL, typed decoders
migrations/001_create_posts.sql
Every generated file looks like something a skilled Gleam developer would write by hand. There is no "framework code" vs "your code" — you own everything.
case wisp.path_segments(req), req.method {
[], http.Get -> home_handler.index(req, ctx)
["posts"], http.Get -> post_handler.index(req, ctx)
["posts", "new"], http.Get -> post_handler.new(req, ctx)
["posts"], http.Post -> post_handler.create(req, ctx)
["posts", id], http.Get -> post_handler.show(req, ctx, id)
["posts", id, "edit"], http.Get -> post_handler.edit(req, ctx, id)
["posts", id], http.Put -> post_handler.update(req, ctx, id)
["posts", id], http.Delete -> post_handler.delete(req, ctx, id)
_, _ -> error_handler.not_found(req)
}Plain Gleam pattern matching. No DSL, no macros. A new developer reads this file and understands every route in 30 seconds.
| Command | Description |
|---|---|
refrakt new <name> |
Create a new project (--db postgres, --db sqlite) |
refrakt gen resource <name> <fields> |
Full CRUD — handler, views, form, domain, repo, migration, tests |
refrakt gen resource <name> <fields> --api |
JSON API — handler, domain, repo, migration (no views) |
refrakt gen page <name> |
Static page — handler + route |
refrakt gen auth |
Authentication — login, register, logout, sessions, middleware |
refrakt gen island <name> |
Lustre interactive island (client-side) |
refrakt gen live <name> |
Lustre server component (real-time over WebSocket) |
refrakt gen migration <name> |
SQL migration file |
refrakt migrate |
Run pending migrations |
refrakt build |
Compile Lustre islands to JavaScript |
refrakt dev |
Dev server with file watching (auto-rebuild) |
refrakt routes |
Print the route table |
Conventions over assembly — One project layout. One routing shape. One way to structure handlers, views, forms, and repos. Spend time building features, not debating file organization.
Generated code is your code — Every file the CLI creates is plain Gleam you can read, modify, and own. No hidden framework internals.
No magic — Routing is pattern matching. Views are functions. Validation is functions. If you can read Gleam, you can read a Refrakt app.
Build on the ecosystem — Wisp handles HTTP. Lustre handles HTML. Mist runs the server. Pog or Sqlight talk to the database. Refrakt adds conventions and generators — it doesn't reinvent the stack.
- Project scaffolding with Postgres or SQLite
- Full CRUD resource generator (handler, views, forms, domain, repo, migration, tests)
- JSON API mode (
--apiflag, routes under/api/) - Authentication generator (login, register, logout, sessions, middleware)
- Lustre interactive islands (
gen island) - Lustre server components (
gen live) with WebSocket transport - Migration runner (auto-generates and runs migration module)
- Validation helpers (required, min/max length, inclusion, format)
- Flash messages (signed cookies)
- Test helpers (request builders)
- Dev error page (dark theme, error details, stack trace, request info)
- Dev file watcher (auto-rebuild on
src/changes via fswatch) - Auto-format all generated code
- Route table printer
- 21 tests (12 unit + 9 integration)
- 17 documentation files
- 2 example apps (blog + tasks)
gleam run -m refrakt/cli -- new blog --db postgres
cd blog
gleam run -m refrakt/cli -- gen resource posts title:string body:text published:bool
gleam run -m refrakt/cli -- gen auth
gleam run -m refrakt/cli -- gen page aboutSee examples/blog/ for the complete app.
gleam run -m refrakt/cli -- new tasks_app --db sqlite
cd tasks_app
gleam run -m refrakt/cli -- gen resource tasks title:string completed:boolSee examples/tasks_app/ for the complete app.
| Guide | Description |
|---|---|
| Installation | Prerequisites, install, first project |
| Tutorial: Build a Blog | 10 steps from refrakt new to working app |
| Project Structure | Directory layout, three layers, dependency flow |
| Routing | Pattern matching, params, middleware |
| Handlers | Request handling, responses, JSON |
| Views & Templates | Lustre HTML, layouts, components |
| Forms & Validation | Typed decoders, validation helpers |
| Database | Postgres, SQLite, repos, migrations |
| Authentication | Sessions, middleware, customization |
| Testing | Generated tests, test helpers |
| Deployment | Production builds, Docker, Fly.io |
| CLI Reference | All commands with flags and examples |
| Configuration | Environment variables, config types |
| Field Types | All types with Gleam/HTML/SQL mappings |
| Lustre Integration | Islands and server components |
| Package | Role |
|---|---|
| Wisp | HTTP handlers, middleware, request/response |
| Lustre | HTML templating, interactive islands, server components |
| Mist | HTTP server, WebSocket |
| Pog | PostgreSQL client |
| Sqlight | SQLite client |
git clone https://github.com/raskell-io/refrakt.git
cd refrakt
# Install toolchain
mise install # Gleam 1.14, Erlang 27, rebar3
# Build and test
gleam build
gleam test # 21 testsMIT — see LICENSE.