A minimal web framework for CHICKEN Scheme, inspired by Sinatra. Schematra is currently an early exploration project created for learning purposes, but hopefully it will grow into something more useful over time.
I created Schematra because I wanted to:
- Improve my knowledge of scheme: Building a web framework is a great way to explore a language's capabilities and idioms
- Create something simple: Most web frameworks are complex beasts. Schematra aims to be minimal and understandable
- Enable modern web development: The framework is designed to work well with modern tools like Tailwind CSS and htmx, making it easy to build interactive web applications without heavy JavaScript frameworks. Although tbh this is completely agnostic to how the framework works, it's what most of my examples will use.
- Simple route definition with get and post functions
- URL parameter extraction (e.g., /users/:id) & body parsing
- Middleware support
- Included naive session middleware (cookie storage)
- Development mode with REPL integration (leveraging emacs run-scheme)
- Very simple hiccup inspired template system
- Built on top of the solid Spiffy web server
First, make sure you have CHICKEN Scheme installed. Then install the required dependencies:
For development mode, you'll also need:
Next step would be to build schematra & the core modules:
Here's a simple "Hello World" application:
Save this as app.scm and run:
Visit http://localhost:8080 to see your application running.
For interactive development, start the server in development mode:
This starts the web server in a background thread and opens an NREPL on port 1234. You can connect with your favorite Scheme editor or use nc localhost 1234 for a simple REPL session.
For a more elegant environment, you can use emacs run-scheme by running C-u M-x run-scheme RET nc localhost 1234.
Schematra supports URL parameters using the :parameter syntax, as well as query params:
The params argument contains both URL parameters (with string keys) and query parameters (with symbol keys).
Route handlers are functions that process HTTP requests and generate responses. Understanding how they work and what they should return is crucial for building Schematra applications.
Every route handler must accept exactly two arguments:
- request: The intarweb request object containing headers, method, URI, and request port
- params: An association list containing both URL path parameters and query parameters
The request parameter provides access to all aspects of the HTTP request:
Common request operations:
- (request-method request) - Get HTTP method (GET, POST, etc.)
- (request-uri request) - Get URI object with path, query, etc. (see uri-common)
- (request-headers request) - Get request headers
- (request-body-string request) - Read request body as string (useful for POST data)
The params argument is an association list containing two types of parameters:
- Path Parameters (string keys): Extracted from URL segments starting with :
- Query Parameters (symbol keys): Extracted from the URL query string
Route handlers can return different types of values, which Schematra automatically converts to the corresponding intarweb response:
Return a string to send a 200 OK response with that string as the body:
Return a list in the format (status body [headers]) for full control over the response:
Some common valid status symbols include:
- ok (200)
- created (201)
- found (302) - for redirects
- bad-request (400)
- unauthorized (401)
- forbidden (403)
- not-found (404)
- internal-server-error (500)
- And many others following HTTP status code conventions
Schematra provides helper functions for common response patterns:
Redirect and halt both generate a specific signal that's captured by the main router and short-circuit any other processing: no other middleware or part of the route handler will be executed.
For HTML responses, use the included Chiccup template system:
For POST requests, you can easily access the request body using request-body-string:
Since you have access to the intarweb request object, you can also access the object and its port directly if you want.
Schematra supports middleware functions that can process requests before they reach your route handlers. Middleware is useful for cross-cutting concerns like authentication, logging, request parsing, and session management.
Install middleware using the use-middleware! function:
Middleware functions have the following signature:
- request: The HTTP request object
- params: The route and query parameters alist
- next: A thunk (zero-argument function) that calls the next middleware in the chain or the final route handler
Middleware is executed in the order it's installed with use-middleware!. The first middleware installed runs first on the request, and last on the response:
Schematra includes session middleware for cookie-based session management. See the "Session Management" section for details on using the session middleware.
Schematra plays nicely with modern web development tools:
Include Tailwind via CDN in your HTML responses:
Add htmx for dynamic interactions:
Schematra includes a simple session middleware that stores session data in HTTP cookies. Sessions are automatically serialized and deserialized on each request.
First, install the session middleware with a secret key:
Then use session functions in your route handlers:
- (session-get key [default]) - Retrieve a value from the session
- (session-set! key value) - Store a value in the session
- (session-delete! key) - Remove a key from the session
You can customize session behavior using parameters:
- Sessions are stored as serialized data in cookies (client-side storage)
- The secret key is used for session identification but not encryption
- Avoid storing sensitive data in sessions
- Consider implementing proper encryption/signing for production use
- Session cookies are HTTP-only by default to prevent JavaScript access
This is still an exploration project! Schematra is still in early development and should not be used for production applications. Currently we have:
- Limited error handling
- Simple HTML rendering library chiccup, a hiccup-inspired rendering engine.
- Middleware system, with a couple of core modules to provide some basic services (sessions, csrf, oauth2)
- SSE support (will add WebSockets soon)
- No database integration, but you can use any database egg and create a middleware to provide a persistance layer.
- No background job system (working on one though, using the hiredis wrapper)
While not ready for production, it's perfect for:
- Learning Scheme
- Prototyping simple web applications
- Experimenting with htmx and Tailwind CSS
- Understanding how web frameworks work under the hood
If you find Schematra interesting and want to help it grow beyond a toy project, contributions are welcome! Feel free to:
- Report bugs or suggest features via GitHub issues
- Submit pull requests with improvements
- Share your experience using Schematra
- Help improve the documentation
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
See the source code for the complete license text.
.png)



