README.md
July 28, 2026 Ā· View on GitHub
š· Jazzy Framework
Write Less Code, Build More Features.
The high-performance, batteries-included web framework for Nim.
Why Jazzy? ⢠Power Snippet ⢠Quick Start ⢠Features in Depth ⢠Documentation
Why Jazzy?
When building a web application, piecing together third-party libraries, wiring up middleware, and hand-crafting database or auth infrastructure is a massive time sink.
Jazzy Framework is a batteries-included web framework designed for maximum developer productivity. From authentication and declarative validation to a fluent database query builder and the Melody template engine, everything you need to ship production web apps comes built right in. Powered by the multi-threaded Mummy HTTP server under the hood, Jazzy delivers blazing-fast performance without sacrificing developer experience.
š„ļø Building Desktop Apps? Check out Jazzy Desktop ā build cross-platform desktop applications powered by Jazzy Framework & React / Vue / Svelte under the hood!
EVERYTHING YOU NEED TO SHIP IT
- ā” Lightning Fast Core: Multi-threaded Mummy HTTP engine under the hood for maximum throughput.
- š”ļø Built-in Auth & Security: Out-of-the-box JWT Authentication, Basic Auth, Rate Limiting, and CORS protection.
- š¾ Fluent DB Query Builder: Expressive, thread-safe SQLite query and schema builder running in WAL mode.
- ā
Declarative Validation: Expressive validation rules that automatically return
422 Unprocessable Entityon failure. - šØ Melody Template Engine: Nim-native HTML rendering engine with zero allocations, layout inheritance, and hot-reload.
- āļø Zero Setup & Dev UI: Automatic
.envloading and a built-in/dev-uidashboard for real-time monitoring during development.
š” Developer Mode UI: When running in dev mode (
Jazzy.serve(8080)), navigate tohttp://localhost:8080/dev-uiin your browser to inspect routes, request logs, and memory cache in real time.
THE POWER SNIPPET
Validating input, persisting to the database, and returning a structured response ā all in a single clean handler:
proc createTodo*(ctx: Context) {.async.} =
# 1. VALIDATE (Automatic 422 JSON response on failure)
let data = ctx.validate(%*{
"title": "required|min:3",
"priority": "int|between:1,5"
})
# 2. DATABASE (Fluent API)
let id = DB.table("todos").insert(%*{
"title": data["title"].getStr,
"priority": data["priority"].getInt,
"completed": 0
})
# 3. RESPONSE
ctx.status(201).json(%*{"id": id, "status": "created"})
QUICK START
1. Install
nimble install jazzy
2. Create app.nim
import jazzy
proc home(ctx: Context) =
ctx.text("Hello Jazzy!")
Route.get("/", home)
Jazzy.serve(8080)
3. Run It
nim c -r app.nim
FEATURES IN DEPTH
1. Context-First Architecture (ctx)
Every handler receives a thread-safe Context object managing the request and response lifecycle:
- Input Gathering:
ctx.input("key")(Automatically searches query params, JSON body, and form payloads). - Auth & Sessions:
ctx.login(userNode),ctx.logout(),ctx.check(). - Response Helpers:
ctx.json(...),ctx.text(...),ctx.html(...),ctx.render(...).
2. Melody Template Engine (Nim Syntax)
A zero-allocation, clean HTML rendering engine with native Nim syntax and layout inheritance:
<!-- views/layouts/app.html (Parent Layout) -->
<!DOCTYPE html>
<html>
<body>
@include "partials/navbar"
<main>
@yield "content"
</main>
</body>
</html>
<!-- views/home.html (Child View) -->
@extends "layouts/app"
@section "content"
<h1>Welcome, {{ $user.name }}!</h1>
@if user.isAdmin
<p>Admin Dashboard</p>
@else
<p>User Dashboard</p>
@endif
<ul>
@for item in todos
<li>{{ $item.title }}</li>
@endfor
</ul>
@endsection
3. Database & Schema Builder
Thread-safe SQLite query builder operating in WAL mode:
# Fetching Data
let users = DB.table("users").where("active", 1).get()
# Schema Migrations
createTable("users")
.increments("id")
.string("email", nullable = false)
.execute()
4. Routing & Middleware Guards
Route.groupPath("/admin", @[authGuard, cors()]):
Route.get("/dashboard", handleDashboard)
5. Memory Cache
Thread-safe in-memory cache shared across all Mummy worker threads:
ctx.cache.put("stats", data, ttl = 3600)
š View More Code Examples (Controllers, Middleware, Redirects...)
Controller / Handler Example (isNull Helper)
proc showProfile*(ctx: Context) {.async.} =
let userId = ctx.param("id")
let user = DB.table("users").where("id", userId).first()
# Using Jazzy's built-in isNull helper
if user.isNull():
ctx.status(404).json(%*{"error": "User not found"})
return
ctx.render("profile", %*{"user": user})
Custom Middleware
let customHeaderMiddleware* = Middleware(
name: "CustomHeader",
handler: proc(ctx: Context, next: HandlerProc) {.async.} =
ctx.header("X-Framework", "Jazzy")
# Crucial: Always call next(ctx) to continue the middleware chain
await next(ctx)
)
Redirects & Custom Response Headers
proc handleOldUrl*(ctx: Context) =
# 302 Redirect
ctx.redirect("/new-url")
proc handleDownload*(ctx: Context) =
# Custom response headers and raw payload
ctx.header("Content-Type", "application/pdf")
ctx.text("PDF Binary Content")
DOCUMENTATION
š For full documentation, guides, and comprehensive API references: š Jazzy Framework Documentation