Next-generation Dart server framework. Build modern servers and deploy them to the runtime you prefer.
Install the package:
dart pub add spryCreate a minimal project structure:
.
├─ routes/
│ └─ index.dart
└─ spry.config.dart
spry.config.dart
import 'package:spry/config.dart';
void main() {
defineSpryConfig(
host: '127.0.0.1',
port: 4000,
target: BuildTarget.vm,
);
}routes/index.dart
import 'package:spry/spry.dart';
Response handler(Event event) {
return Response.json({
'message': 'hello from spry',
'runtime': event.context.runtime.name,
'path': event.url.path,
});
}Start the dev server:
dart run spry serveroutes/defines request handlers with file routingmiddleware/and_middleware.dartshape cross-cutting request behavior_error.dartprovides scoped error handlingdefineHandler(...)adds handler-local middleware and error handlingpublic/serves static assets directlyspry.config.dartselects the runtime target and build behavior
Spry can generate an openapi.json document as part of the normal build
pipeline.
Use package:spry/config.dart for the build-side config and
package:spry/openapi.dart for the document objects:
import 'package:spry/config.dart';
import 'package:spry/openapi.dart';
void main() {
defineSpryConfig(
openapi: OpenAPIConfig(
document: OpenAPIDocumentConfig(
info: OpenAPIInfo(title: 'Spry API', version: '1.0.0'),
),
output: OpenAPIOutput.route('openapi.json'),
),
);
}Route files can expose top-level openapi metadata:
import 'package:spry/openapi.dart';
final openapi = OpenAPI(
summary: 'List users',
tags: ['users'],
);Key rules:
OpenAPIConfig.document.componentsdefines document-level components.- Route-level
OpenAPI(..., globalComponents: ...)is lifted into documentcomponentsduring generation. - A route without a method suffix expands to
GET,POST,PUT,PATCH,DELETE, andOPTIONSin OpenAPI. HEADis only emitted when a route explicitly defines.head.dart.OpenAPIOutput.route('openapi.json')writes the file intopublic/, so it is served like any other static asset.
Spry can emit output for:
| Target | Runtime | Deploy Docs |
|---|---|---|
vm |
Dart VM | Dart VM |
exe |
Native executable | Native executable |
aot |
AOT snapshot | AOT snapshot |
jit |
JIT snapshot | JIT snapshot |
kernel |
Kernel snapshot | Kernel snapshot |
node |
Node.js | Node.js |
bun |
Bun | Bun |
deno |
Deno | Deno |
cloudflare |
Cloudflare Workers | Cloudflare Workers |
vercel |
Vercel | Vercel |
netlify |
Netlify Functions | Netlify Functions |
Spry exposes websocket upgrades from the request event without introducing a second routing system.
import 'package:spry/spry.dart';
import 'package:spry/websocket.dart';
Response handler(Event event) {
if (!event.ws.isSupported || !event.ws.isUpgradeRequest) {
return Response('plain http fallback');
}
return event.ws.upgrade((ws) async {
ws.sendText('connected');
await for (final message in ws.events) {
switch (message) {
case TextDataReceived(text: final text):
ws.sendText('echo:$text');
case BinaryDataReceived():
case CloseReceived():
break;
}
}
}, protocol: 'chat');
}Current websocket support follows the underlying osrv runtime surface:
- supported: Dart VM, Node.js, Bun, Deno, Cloudflare Workers
- unsupported: Vercel, current Netlify Functions runtime
Read the documentation at spry.medz.dev.
Start here:
Spry framework is an MIT licensed open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider sponsoring Seven(@medz) development.
Thank you to all the people who already contributed to Spry!