fletch 2.0.1 copy "fletch: ^2.0.1" to clipboard
fletch: ^2.0.1 copied to clipboard

A fast, Express-inspired HTTP framework for Dart. Build production-ready REST APIs with built-in sessions, CORS, rate limiting, and middleware support.

Fletch Logo Fletch


pub package License: MIT

πŸ“¦ Package History Notice
This package was previously a jQuery-like library by Rob Kellett. As of version 2.0.0 (January 2025), it has been repurposed as an Express-inspired HTTP framework. If you're looking for the original jQuery-like library, please see version 0.3.0 or the original repository. Thank you to Rob for graciously transferring the package name!

An Express-inspired HTTP framework for Dart. It brings familiar routing, middleware, and dependency-injection patterns to dart:io while remaining lightweight and dependency-free beyond GetIt.

πŸ“š Documentation | πŸ› Issues | πŸ’¬ Discussions

Why Fletch? #

If you're coming from Express.js or Node.js, Fletch will feel instantly familiar:

  • βœ… Express-like API - app.get(), app.post(), middleware, it's all here
  • ⚑ Fast - Radix-tree routing, minimal overhead
  • πŸ”’ Secure by default - HMAC-signed sessions, CORS, rate limiting built-in
  • 🎯 Production-ready - Graceful shutdown, request timeouts, error handling
  • 🧩 Modular - Controllers, isolated containers, dependency injection
  • πŸ“¦ Lightweight - Minimal dependencies, pure Dart

Features #

  • Fast radix-tree router with support for path parameters and nested routers
  • Middleware pipeline with global and per-route handlers
  • GetIt-powered dependency injection (supports async/lazy registrations)
  • Controller abstraction for modular route registration
  • Optional isolated containers for mounting self-contained sub-apps
  • Batteries-included middleware for CORS, rate limiting, and cookie parsing

Quick start #

dart pub add fletch
import 'dart:io';

import 'package:fletch/fletch.dart';

Future<void> main() async {
  final app = Fletch();

  app.use(app.cors(allowedOrigins: ['http://localhost:3000']));
  app.get('/health', (req, res) => res.text('OK'));

  final port = int.parse(Platform.environment['PORT'] ?? '8080');
  await app.listen(port);
  print('Listening on http://localhost:$port');
}

Routing essentials #

  • Use app.get, app.post, etc. to register handlers. Supply optional middleware with the middleware: argument.

  • Controllers help organise routes:

    class UsersController extends Controller {
      @override
      void registerRoutes(ControllerOptions options) {
        options.get('/', _list);
        options.get('/:id(\\d+)', _show);
      }
    }
    
    app.useController('/users', UsersController());
    
  • Throw one of the built-in HttpError types (NotFoundError, ValidationError, etc.) to short-circuit with a specific status code.

Working with dependencies #

The container is backed by GetIt. Register dependencies during startup and retrieve them in handlers via request.container:

app.registerLazySingleton(() => Database(config));

app.get('/posts', (req, res) async {
  final db = req.container.get<Database>();
  final posts = await db.posts();
  res.json({'data': posts});
});

Isolated modules #

IsolatedContainer lets you mount a self-contained sub-application that has its own middleware, router, and DI scope while sharing the main server:

final admin = IsolatedContainer(prefix: '/admin');
admin.use((req, res, next) {
  res.setHeader('X-Isolated', 'admin');
  return next();
});
admin.get('/', (req, res) => res.text('Admin dashboard'));
admin.mount(app);

For integration testing or microservice setups you can host the isolated module by itself:

await admin.listen(9090); // optional

Example project #

See example/fletch_example.dart for a full reference that demonstrates controllers, isolated modules, and common middleware.

Error handling #

Install a global error handler to customise responses:

app.setErrorHandler((error, req, res) async {
  if (error is ValidationError) {
    res.json({'error': error.message, 'details': error.data},
        statusCode: error.statusCode);
    return;
  }

  res.setStatus(HttpStatus.internalServerError);
  res.json({'error': 'Internal Server Error'});
});

Performance tips #

  • Deploy behind a reverse proxy (nginx, Caddy) that terminates TLS and handles static assets.

  • Reuse the same Fletch instance across isolates if you need more CPU headroomβ€”each isolate can call await app.listen(port, address: ...) with a different binding.

  • For load testing use tools like wrk or hey`:

    wrk -t8 -c256 -d30s http://localhost:8080/health
    

    Test both direct routes and isolated modules to compare overhead.

  • Request parsing currently buffers the entire body; set upstream limits (e.g. via load balancer) and prefer streaming uploads for very large payloads.

Documentation #

Full documentation is available at docs.fletch.mahawarkartikey.in.

Contributing #

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run dart format . and dart analyze
  4. Add tests for new features
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

File issues or feature requests in the repository issue tracker.

License #

MIT License.

3
likes
130
points
123
downloads

Publisher

verified publishermahawarkartikey.in

Weekly Downloads

A fast, Express-inspired HTTP framework for Dart. Build production-ready REST APIs with built-in sessions, CORS, rate limiting, and middleware support.

Homepage
Repository (GitHub)
View/report issues

Topics

#http #server #backend-framework #express #rest-api

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

args, async, crypto, get_it, http, logger, meta, mime, uri, uuid, xml

More

Packages that depend on fletch