Native H2O Core
Request handling runs on H2O — a high-performance C HTTP server — connected through Dart FFI. One worker Isolate per CPU core shares the socket via SO_REUSEPORT.
How it works
A native H2O core over FFI, an Express-style API you already know, and multi-core scaling out of the box — build production backends in pure Dart.
A familiar, ergonomic API. If you've used Express or Fiber, you already know Daho.
import 'package:daho/daho.dart';
// Route setup MUST be a top-level function — it re-runs on every worker Isolate.
void setupRoutes(Daho app) {
app.use(Middlewares.logger()); // access log
app.get('/', (req, res) => res.ok({'hello': 'world'})); // 200 JSON
app.get('/users/:id', (req, res) => res.ok({'id': req.params['id']}));
app.post('/users', (req, res) => res.status(201).json(req.body)); // echo body
}
void main() {
final app = Daho(config: const DahoConfig(bodyLimit: 8 * 1024 * 1024));
app.listen(8080, routes: setupRoutes, onStart: () => print('http://127.0.0.1:8080'));
}Install the native toolchain once, add the package, and run.
Daho's core is native. On macOS: brew install h2o cmake. On Debian/Ubuntu, H2O isn't in the apt archive, so it's built from source — see Getting Started.
Run dart pub add daho, or scaffold a full project with the CLI: daho create my_api.
The CLI compiles the native library on first run: daho run. That's it — your server is live.
A C event loop does the heavy lifting; Dart handles your logic.
Multi-worker scaling is linear with cores on Linux. On macOS a single worker is used because of an SO_REUSEPORT limitation. See the performance guide →
Go from zero to a running API in minutes.