Kemal is a Fast, Effective, Simple web framework for Crystal.
Hello everyone,
Kemal 1.10.0 is here
This is the biggest Kemal release to date: a modular router, a clearer way to plug in middleware, richer response helpers, and several reliability fixes across routing, the CLI, and request parsing ![]()
Modular Kemal::Router
You can now build namespaced apps with scoped filters, WebSocket routes, and flexible mounting—while the classic top-level DSL stays fully supported.
require "kemal"
api = Kemal::Router.new
api.namespace "/users" do
get "/" do |env|
env.json({users: ["alice", "bob"]})
end
get "/:id" do |env|
env.text "user #{env.params.url["id"]}"
end
end
mount "/api/v1", api
Kemal.run
This makes it easier to organize large APIs, version routes, and reuse sub-applications without losing Kemal’s familiar style.
The use keyword for middleware
Register global or path-specific middleware in one place. You can pass a single handler, an array of handlers, and control where they sit in the chain.
require "kemal"
# Path-specific middlewares for /api routes
use "/api", [CORSHandler.new, AuthHandler.new]
get "/" do
"Public home"
end
get "/api/users" do |env|
env.json({users: ["alice", "bob"]})
end
Kemal.run
Chainable response helpers
Response helpers are chainable for JSON, HTML, text, and XML. They understand HTTP::Status (including symbols like :created), and you can halt with a fully built response—handy for short API error paths.
require "kemal"
get "/users" do |env|
env.json({users: ["alice", "bob"]})
end
post "/users" do |env|
env.status(:created).json({id: 1, created: true})
end
get "/admin" do |env|
halt env.status(403).html("<h1>Forbidden</h1>")
end
get "/api/users" do |env|
env.json({data: ["alice", "bob"]}, content_type: "application/vnd.api+json")
end
Kemal.run
Filters and routing correctness
- Wildcard filters: Global wildcard filters now always run as intended, while namespace filters stay scoped to their routes—so behavior matches what you expect in modular apps.
- Route LRU cache: The route lookup cache is now concurrency-safe thanks to a Mutex, which matters under parallel request handling.
-
OverrideMethodHandler: Fixed a route cache bug when using the_methodparameter for HTTP verb override (e.g. in HTML forms).
CLI and request body
- CLI: SSL validation and option parsing were tightened, with expanded specs around CLI behavior.
-
ParamParser#raw_body: Handlers can read the raw body multiple times when needed (for example alongside kemal-session), while still using parsed body params elsewhere.
post "/" do |env|
raw = env.params.raw_body # raw body, multiple handlers can call it
env.params.body["name"] # parsed body
end
Thanks for using and supporting Kemal. Full details and links to the related pull requests are in the v1.10.0 release notes.
P.S: You can support Kemal development via Github Sponsors ![]()
Happy Crystalling ![]()
