Fast, Effective, Simple Web Framework
3,912
stars
886
commits
Crystal
primary language
Sep 11, 2026
updated
Build web applications and APIs with minimal code. 3.8k+ ⭐, 5M+ downloads since 2015.
Create a new project
crystal init app my-app
cd my-app
Add Kemal to shard.yml
dependencies:
kemal:
github: kemalcr/kemal
Write your app - replace src/my-app.cr with:
require "kemal"
get "/" do
"Hello World!"
end
get "/api" do |env|
env.response.content_type = "application/json"
{status: "ok"}.to_json
end
Kemal.run
Install dependencies and run
shards install
crystal run src/my-app.cr
Visit http://localhost:3000 - done in under a minute. 🚀
| Problem | Solution |
|---|---|
| "I want C-level performance with Ruby-like syntax" | Crystal + Kemal - fast by default |
| "I need WebSocket support out of the box" | Built-in, no extra gems |
| "Building a JSON API" | Native JSON handling, minimal boilerplate |
| "I want a framework that stays out of my way" | No forced ORM, no magic, just Crystal |
Kemal is built on Crystal. It compiles to native code and starts instantly.
| Test | Results |
|---|---|
| JSON serialization (100 conn) | ~50,000 req/sec |
| Hello World (100 conn) | ~85,000 req/sec |
| Static file serving | ~40,000 req/sec |
| Memory per request | ~0.5 KB |
| Binary size | ~2 MB (with dependencies) |
No JVM, no Node, no Ruby VM. Just a native binary.
| Feature | Kemal | Sinatra | Flask | Express |
|---|---|---|---|---|
| Performance (req/sec) | ~85K | ~5K | ~3K | ~15K |
| WebSocket built-in | ✅ | - | - | - |
| Single binary deploy | ✅ | - | - | - |
| JSON handling | Native | Gem | Extension | Native |
| Type safety | ✅ | - | - | - |
| Concurrency | Fibers | Threads | Threads | Async |
Kemal aims to be a simple, fast and reliable foundation for building production-grade web applications and APIs in Crystal.
Is Kemal production ready?
Yes. Kemal has been used in production since 2015 with 5M+ downloads.
Does Kemal support WebSocket?
Yes, built-in. No extra dependencies needed.
Can I build a REST API with Kemal?
Yes. JSON handling is built-in. Return hashes or JSON directly from routes.
Does Kemal support the HTTP QUERY method?
Yes. QUERY (RFC 10008) is a safe, idempotent method that carries the query in the request body instead of the URL:
query "/search" do |env|
q = env.params.json["q"]? # or env.params.body for form-encoded queries
search_products(q).to_json
end
before_query / after_query filters and Kemal::Router#query work like every other verb. A QUERY request that has a body but no Content-Type header is rejected with 400 per the RFC.
Does Kemal work with any ORM?
Yes. You can use any Crystal ORM or database library. No forced dependencies.
How is Kemal different from Sinatra / Flask / Express?
Kemal compiles to a native binary with Crystal. You get C-like performance, type safety, and single-binary deployment. Sinatra and Flask are interpreted. Express runs on Node's event loop.
If Kemal helps you or your company, consider sponsoring. Your support helps me maintain Kemal and build the Crystal ecosystem full time.
We love contributions! Please read our Contributing Guide.
To report a security vulnerability, please see our Security Policy.
Special thanks to Manas for their work on Frank.
MIT
Crystal
99.8%
Fast, Effective, Simple Web Framework
3,912
stars
886
commits
Crystal
primary language
Sep 11, 2026
updated
Build web applications and APIs with minimal code. 3.8k+ ⭐, 5M+ downloads since 2015.
Create a new project
crystal init app my-app
cd my-app
Add Kemal to shard.yml
dependencies:
kemal:
github: kemalcr/kemal
Write your app - replace src/my-app.cr with:
require "kemal"
get "/" do
"Hello World!"
end
get "/api" do |env|
env.response.content_type = "application/json"
{status: "ok"}.to_json
end
Kemal.run
Install dependencies and run
shards install
crystal run src/my-app.cr
Visit http://localhost:3000 - done in under a minute. 🚀
| Problem | Solution |
|---|---|
| "I want C-level performance with Ruby-like syntax" | Crystal + Kemal - fast by default |
| "I need WebSocket support out of the box" | Built-in, no extra gems |
| "Building a JSON API" | Native JSON handling, minimal boilerplate |
| "I want a framework that stays out of my way" | No forced ORM, no magic, just Crystal |
Kemal is built on Crystal. It compiles to native code and starts instantly.
| Test | Results |
|---|---|
| JSON serialization (100 conn) | ~50,000 req/sec |
| Hello World (100 conn) | ~85,000 req/sec |
| Static file serving | ~40,000 req/sec |
| Memory per request | ~0.5 KB |
| Binary size | ~2 MB (with dependencies) |
No JVM, no Node, no Ruby VM. Just a native binary.
| Feature | Kemal | Sinatra | Flask | Express |
|---|---|---|---|---|
| Performance (req/sec) | ~85K | ~5K | ~3K | ~15K |
| WebSocket built-in | ✅ | - | - | - |
| Single binary deploy | ✅ | - | - | - |
| JSON handling | Native | Gem | Extension | Native |
| Type safety | ✅ | - | - | - |
| Concurrency | Fibers | Threads | Threads | Async |
Kemal aims to be a simple, fast and reliable foundation for building production-grade web applications and APIs in Crystal.
Is Kemal production ready?
Yes. Kemal has been used in production since 2015 with 5M+ downloads.
Does Kemal support WebSocket?
Yes, built-in. No extra dependencies needed.
Can I build a REST API with Kemal?
Yes. JSON handling is built-in. Return hashes or JSON directly from routes.
Does Kemal support the HTTP QUERY method?
Yes. QUERY (RFC 10008) is a safe, idempotent method that carries the query in the request body instead of the URL:
query "/search" do |env|
q = env.params.json["q"]? # or env.params.body for form-encoded queries
search_products(q).to_json
end
before_query / after_query filters and Kemal::Router#query work like every other verb. A QUERY request that has a body but no Content-Type header is rejected with 400 per the RFC.
Does Kemal work with any ORM?
Yes. You can use any Crystal ORM or database library. No forced dependencies.
How is Kemal different from Sinatra / Flask / Express?
Kemal compiles to a native binary with Crystal. You get C-like performance, type safety, and single-binary deployment. Sinatra and Flask are interpreted. Express runs on Node's event loop.
If Kemal helps you or your company, consider sponsoring. Your support helps me maintain Kemal and build the Crystal ecosystem full time.
We love contributions! Please read our Contributing Guide.
To report a security vulnerability, please see our Security Policy.
Special thanks to Manas for their work on Frank.
MIT
Crystal
99.8%