Skip to content

Spry 7Ship Cross-Runtime Dart Servers

Next-generation Dart server framework. Build modern servers and deploy them to the runtime you prefer.

Start local

Develop with spry serve

Stay inside a normal Dart project, add a routes/ tree, and let Spry build and serve the generated app during development.

Deploy wide

Target the runtime you need

Use defineSpryConfig(...) to control host, port, output, reload behavior, and build target without changing your route code.

Stay inspectable

Generated output is part of the story

Spry does not hide its runtime entry. The scanner emits a real app and a real main file so the build stays understandable.

Build from the file tree

Spry v7 is organized around a runtime pipeline, not around imperative route registration. The folder tree is the contract. Route files define handlers. _middleware.dart and _error.dart shape behavior by scope. spry.config.dart decides how the generated output should run.

text
.
├─ routes/
│  ├─ index.dart
│  ├─ about.get.dart
│  ├─ users/[id].dart
│  ├─ [...slug].dart
│  ├─ _middleware.dart
│  └─ _error.dart
├─ middleware/
│  └─ 01_logger.dart
├─ public/
│  └─ hello.txt
├─ hooks.dart
└─ spry.config.dart
dart
import 'package:spry/spry.dart';

Response handler(Event event) {
  return Response.json({
    'message': 'hello from spry',
    'runtime': event.context.runtime.name,
    'path': event.request.url.path,
  });
}
dart
import 'package:spry/config.dart';

void main() {
  defineSpryConfig(
    host: '127.0.0.1',
    port: 4000,
    target: BuildTarget.dart,
  );
}

A sharper way to structure Dart servers

Generated app, direct runtime control

Spry keeps the authoring model simple: folders define routes, scoped files shape behavior, and runtime choice stays in config. The result is less ceremony than a traditional server stack without turning the framework into a black box.

routes/ scannerScoped middlewareScoped error boundariesPublic asset servingLifecycle hooks
  • Handlers return Response values directly.
  • Middleware composes with Next instead of global mutation.
  • Params and locals live on a request-scoped Event object.
  • Targets are selected in config rather than per-route conditionals.
  • A concrete Spry(...) app with route and middleware maps.
  • A runtime-specific main.dart entrypoint.
  • Target extras such as Vercel or Cloudflare wrappers when needed.

Read the docs in the same order you build

  1. Start with Getting Started to get a minimal project running.
  2. Read Project Structure, File Routing, and Middleware and Errors to learn the actual authoring model.
  3. Add Assets, Lifecycle, and Request Context once the basics are in place.
  4. Use Configuration, then move to Deploy Overview when you are ready to run the same code outside Dart VM.

Spry is at its best when the folder layout stays boring and the runtime matrix stays flexible.

That is the design center for the v7 docs. Minimal files, explicit output, and deployment targets that do not force a rewrite.

Released under the MIT License.