Toucan v0.1.0 is the first public release of the framework. The goal is small and practical: make Donna comfortable for building HTTP APIs, server-rendered pages, and real-time browser apps without hiding the request pipeline behind macros or a registration DSL.
Why Toucan exists
Toucan routes are just functions. A Ctx flows through method filters, path
matchers, middleware, and response terminals with Donna's |> operator. A route
that does not match returns Rejected; toucan.try restores the active request
so the next route can attempt a match.
That keeps the model explicit:
fn router(c: toucan.Ctx) -> toucan.Ctx:
c
|> toucan.try(home)
|> toucan.try(api)
|> toucan.not_found
fn home(c: toucan.Ctx) -> toucan.Ctx:
c
|> toucan.get
|> toucan.path("/")
|> toucan.html("<h1>Hello from Toucan</h1>")
What's Included
Pipeline routing — Routes are function chains built with |>. Method
filters, path matchers, and response terminals are all plain functions.
URL parameters — Define :name segments in path patterns. Read captures with toucan.param(c, "name").
Request data — form_field, query_param, header_of, content_type_of, and body_of cover common request handling.
Responses — html, json, ok, created, no_content, redirect, and respond for full control over status and content type. Chain set_header to add arbitrary headers.
Static files — static_dir maps paths to a directory and returns Rejected on miss so subsequent handlers still run.
Security — cors, csp, and secure_headers add the standard defensive headers with a single call. Applied automatically on every response by serve.
Logging — serve_logged and serve_with_logged print coloured request lines. Pass logger.Silent for production.
WebSockets — serve_ws for echo and send-to-client use cases. serve_chat for broadcast — automatically sends each new client its connection ID, then broadcasts the handler's reply to all connected clients.
Shared state — serve_with, serve_with_logged, serve_with_chat, and try_with thread any state value through the handler pipeline without global variables.
Sessions — toucan/session provides a simple in-memory session store, cookie helpers, and the pieces needed for login flows and named chat users.
Examples
The release now ships with runnable examples under examples/. Every example
uses port 8000 so you can start one, test it, stop it, and move to the next:
cd examples/basic
donna run
Included examples:
basic— a minimal route and form handlertodo_sqlite— server-rendered todos backed by SQLitetodo_json_api— REST-style JSON todosauth_login— registration, login, protected pages, and sessionsfile_upload— text uploads and image previews with binary image writesurl_shortener— random slugs, SQLite storage, and redirectshtmx_todos— partial HTML updates with htmxchat_sessions— WebSocket chat with session-backed display names
These examples are intentionally small, but they exercise the framework surface: forms, static assets, template rendering, local state, sessions, SQLite, uploads, redirects, JSON responses, and WebSocket broadcasts.
Notes
Toucan is still a first release. The APIs are intentionally compact, and the
examples favor clarity over production hardening. For example, auth_login uses
a demo password hash, and file_upload keeps image uploads bounded so the
current Donna string/runtime path stays stable.
Getting started
Add Toucan to your donna.toml:
toucan = { git = "https://github.com/NikolasSkyl/toucan", version = ">=0.1.0 and <1.0.0" }
Then read the Getting Started guide.