netto 0.1.2
netto: ^0.1.2 copied to clipboard
A minimal, flexible, composable, and neat web framework for Dart.
Netto #
_ __ __ __
/ | / /__ / /_/ /_____
/ |/ / _ \/ __/ __/ __ \
/ /| / __/ /_/ /_/ /_/ /
/_/ |_/\___/\__/\__/\____/
A minimal, flexible, composable, and neat web framework for Dart.
Netto is a web framework whose goal is to give you the lightest
possible foundation for building feature-rich web servers and applications. It
sticks closely to the dart:io
library, adding zero hard wrappers,
and no file system based routing conventions.
Inspired by the ergonomics of Echo in
the Go ecosystem, Netto keeps out of your way so you can structure your server
however you want.
Highlights #
- Familiar
dart:io
surface - Work with the primitives you already know:HttpServer
,HttpRequest
, andHttpResponse
. - Composable middleware - Chain functions with
use
to add logging, authentication, or any custom behavior at either the app or group level. - Typed context storage - Pass data between middleware and handlers using a
per-request
Ctx
with helpers likeset
,get
, andrequire
. - First-class responses - Write strings, JSON, or take over the response stream directly; Netto never hides the socket from you.
- Centralized error handling - Configure an app-wide error handler to produce consistent responses and logging from a single place.
- Radix-tree router - Netto's router is backed by a fast, prefix-based radix tree with support for route groups, named parameters, and all standard HTTP methods.
Quick start #
import "dart:io";
import "package:netto/netto.dart";
Future<void> main() async {
final app = Netto()
..use(logger())
..get("/", (ctx) => ctx.response.string("Hello, Netto!"))
..get("/ping", (ctx) => ctx.response.json({"pong": DateTime.now().toIso8601String()}));
await app.serve(InternetAddress.loopbackIPv4, 8080);
}
Add more routes by calling get
, post
, or group them with group
.
Middlewares run in the order they are registered (globally scoped or group scoped), so you can build your own stack
for logging, authorization, caching, and beyond.
Example using Htmdart and Htmx #
import "dart:io";
import "package:htmdart/htmdart.dart";
import "package:netto/netto.dart";
Future<void> main() async {
final app = Netto()
..get(
"/",
(ctx) => ctx.response.html(
html([
head([
script([
$src("https://unpkg.com/htmx.org@2.0.4"),
]),
]),
body([
h1(["Hello from htmdart + Netto".t]),
button([
$hx.post("/clicked"),
$hx.target("#container"),
"Click me".t,
]),
div([$id("container")]),
]),
]).toHtml(),
),
)
..post(
"/clicked",
(ctx) => ctx.response.html(
div([
$id("container"),
"Button clicked at ${DateTime.now()}".t,
]).toHtml(),
),
);
await app.serve(InternetAddress.anyIPv4, 8080);
}
Next steps #
This README is intentionally light. Detailed guides, patterns, and API explanations will live in the documentation site we are building next. Until then, explore the examples in the examples/ directory and experiment with Netto to see how it fits your projects.