H4
A delightful web framework for Dart — composable, minimal, functional.
Project LinkH4 is a web framework for Dart inspired by h3 from the UnJS ecosystem. It brings the same philosophy to Dart — a small core with composable utility functions instead of bulky middleware chains.
Why H4?
Dart is fast, typed, and underrated as a server language. Most Dart server frameworks feel heavy. H4 takes the opposite approach — your server only runs the code it actually needs.
Composable utilities beat traditional middleware:
- Your server only includes code that is needed
- Extend functionality without global plugins
- Usage is explicit and clean
The API
Five lines to a running server:
import 'package:h4/create.dart';
void main() { var app = createApp(); var router = createRouter(); app.use(router);
router.get("/", (event) => "Hello world!");}Handlers are plain functions. Return a value — H4 serializes it. Return a map — you get JSON. No decorators, no annotations, no magic.
Routing
Dynamic params, wildcards, and modular routers with base paths:
// Dynamic paramsrouter.get('/users/:id', (event) { return 'User ${event.params['id']}';});
// Modular routersvar api = createRouter();app.use(api, basePath: '/api');
api.get('/users', (event) => ['alice', 'bob']);// GET /api/users → ["alice", "bob"]Hooks
Global lifecycle hooks for auth, logging, cleanup — without polluting individual handlers:
var app = createApp( onRequest: (event) { var token = event.headers.value('Authorization'); if (token == null) { throw CreateError(message: 'Unauthorized', errorCode: 401); } event.context['user'] = verifyToken(token); }, onError: (error, event) { logger.error('${event.method} ${event.path}: $error'); }, afterResponse: (event) { analytics.track(event.path); },);Built-in Utilities
File uploads, form parsing, JSON handling — all as composable functions you import when needed:
router.post("/upload", (event) async { var files = await readFiles(event, fieldName: 'file', maxFileSize: 5, hashFileName: true, ); return {'uploaded': files.length};});Error Handling
Throw structured errors anywhere. H4 catches them and returns clean JSON responses:
throw CreateError( message: "Not found", errorCode: 404,);// → {"status": 404, "message": "Not found"}Links
- Documentation — getting started, API reference, guides
- pub.dev — install with
dart pub add h4 - GitHub — source, issues, contributions welcome