crumble
Crumble
A Crystal web framework for server-rendered applications. Crumble wires together typed HTML views, REST-style resources, session handling, and a fingerprinted asset pipeline so you can build full-stack apps in a single binary without any front-end build step. Build your views completely in Crystal with typed DSLs for HTML, CSS and even JavaScript! Finally define your styles right next to your markup to never lose context, but with real CSS instead of clunky frameworks.
Installation
- Add Crumble to your
shard.ymldependencies:
dependencies:
crumble:
github: sbsoftware/crumble
- Install shards and build the CLI:
shards install
Usage
The bin/crumble executable generates a starter layout. A minimal server looks like:
require "crumble"
require "./pages/**"
require "./resources/**"
Crumble::Server.start
Pages
Crumble::Page handles GET requests and automatically derives its route from the class name (ArticlesPage → /articles). Declare a view with the view macro; Crumble will render it into the response and wrap it in an optional layout.
require "css"
class ArticlesPage < Crumble::Page
layout ToHtml::Layout
view do
css_class ArticleListBox
# HTML
template do
div ArticleListBox do
h1 { "Articles" }
ul do
li { "Statically typed HTML, no strings attached." }
end
end
end
# Scoped styles
style do
rule ArticleListBox do
max_width 720.px
margin_top 32.px
margin_left 24.px
margin_right 24.px
font_family "Inter, system-ui, sans-serif"
line_height 1.5
rule "h1" do
margin_bottom 12.px
end
rule "li" do
margin_bottom 6.px
end
end
end
end
end
- Pass a class to
view(SomeView)if you prefer a reusable component. layout SomeLayoutcan reference an existing layout class, which is just something with a#to_html(io : IO)method that yields; when omitted, the view renders bare.
Resources
Crumble::Resource gives you RESTful handlers with sensible defaults for index, show, create, update, and destroy. Routing follows the class name (CommentsResource → /comments); nested paths are supported one level deep via self.nested_path.
require "css"
class CommentsResource < Crumble::Resource
layout ToHtml::Layout
before(:create) { true }
def index
render CommentsView
end
def create
# mutate state, then redirect
redirect uri_path
end
end
class CommentsView
include Crumble::ContextView
css_class CommentsBox
# HTML
template do
div CommentsBox do
h1 { "Comments" }
p { "Hello from a Resource-backed view." }
end
end
# Scoped styles
style do
rule CommentsBox do
background_color "#f8f9fb"
padding 16.px
border_radius 8.px
box_shadow "0 4px 24px rgba(0, 0, 0, 0.06)"
rule "h1" do
margin_bottom 8.px
font_size 22.px
end
rule "p" do
margin_top 0.px
color "#334155"
end
end
end
end
render SomeViewwraps the view in the configured layout and setsContent-Typeto HTML.redirectandredirect_backset a303 See Otherby default.- Add
beforefilters to short-circuit withfalse(400) or anInt32status code.
Server & Routing
Crumble::Server.startboots anHTTP::Serverwith logging and optional OpenTelemetry tracing (CRUMBLE_HOST+--portflag control the bind address).- Sessions are pluggable: override
RequestContext.init_session_storeto switch from the in-memory default to the file-backed store (e.g.FileSessionStore.new("/tmp/sessions")) or your own implementation.
Assets
Use AssetFile to serve fingerprinted static files with cache-busting ETags. Subclasses like PngFile set MIME types for you; just register your files, assigning them to a constant/variable, and they'll be served when used in your markup!
MyPicture = PngFile.register "assets/my_picture.png"
class HomePage < Crumble::Page
view do
template do
div do
img src: MyPicture.uri_path
end
end
end
end
Powered By
- to_html.cr — a typed HTML DSL that emits valid markup at compile time. Crumble extends it with
Crumble::ContextView, giving views access to the request context (ctx) and adding atemplatemacro for concise component definitions. - css.cr — a Crystal CSS builder. Use the
stylemacro to generate stylesheet assets that are automatically appended to the base layout of the site. Classes defined viacss_class/css_idcan be directly used as arguments to CSS rules (rule MyClass do [...] end) as well as HTML tags (div MyClass do [...] end).
Contributing
- Fork the repo and create your branch from
main. - Add or update specs alongside code changes.
- Open a pull request.
Contributors
- Stefan Bilharz (creator & maintainer)
License
MIT
crumble
- 1
- 0
- 0
- 5
- 4
- 1 day ago
- January 5, 2022
MIT License
Wed, 17 Dec 2025 21:09:43 GMT