Configuration
Spry uses spry.config.dart as the single place where runtime behavior is selected. Route files describe your server surface. Config describes how that server should be built and run.
Minimal config
import 'package:spry/config.dart';
void main() {
defineSpryConfig(
host: '127.0.0.1',
port: 4000,
target: BuildTarget.dart,
);
}This file writes JSON that the Spry CLI reads during spry serve and spry build.
API
The public entrypoint is defineSpryConfig(...):
import 'dart:convert';
import 'dart:io';
/// Supported deployment targets for a Spry application.
enum BuildTarget {
/// Runs the application on the Dart VM.
dart,
/// Compiles the application for the Node.js runtime.
node,
/// Compiles the application for the Bun runtime.
bun,
/// Compiles the application for the Cloudflare Workers runtime.
cloudflare,
/// Compiles the application for the Vercel runtime.
vercel,
}
/// Reload behavior used by `spry serve`.
enum ReloadStrategy {
/// Restarts the runtime process after a rebuild.
restart,
/// Keeps the runtime process alive when the target supports hotswap.
hotswap,
}
/// Emits Spry build configuration as JSON for `spry.config.dart`.
void defineSpryConfig({
/// Overrides the host used by `spry serve`.
String? host,
/// Overrides the port used by `spry serve`.
int? port,
/// Selects the target runtime.
BuildTarget? target,
/// Overrides the routes directory.
String? routesDir,
/// Overrides the middleware directory.
String? middlewareDir,
/// Overrides the public asset directory.
String? publicDir,
/// Overrides the generated output directory.
String? outputDir,
/// Overrides the reload strategy used by `spry serve`.
ReloadStrategy? reload,
/// Overrides the Wrangler config path for Cloudflare targets.
String? wranglerConfig,
}) {
final config = <String, Object>{};
if (host != null) {
config['host'] = host;
}
if (port != null) {
config['port'] = port;
}
if (target != null) {
config['target'] = target.name;
}
if (routesDir != null) {
config['routesDir'] = routesDir;
}
if (middlewareDir != null) {
config['middlewareDir'] = middlewareDir;
}
if (publicDir != null) {
config['publicDir'] = publicDir;
}
if (outputDir != null) {
config['outputDir'] = outputDir;
}
if (reload != null) {
config['reload'] = reload.name;
}
if (wranglerConfig != null) {
config['wranglerConfig'] = wranglerConfig;
}
stdout.writeln(
json.encode(config),
);
}Core options
target
Selects which runtime Spry should emit for.
Available values:
BuildTarget.dartBuildTarget.nodeBuildTarget.bunBuildTarget.cloudflareBuildTarget.vercel
This is the most important config field. Everything else should usually stay runtime-agnostic.
host
Overrides the hostname used by spry serve.
defineSpryConfig(
host: '127.0.0.1',
target: BuildTarget.dart,
);port
Overrides the local port used by spry serve.
defineSpryConfig(
port: 4000,
target: BuildTarget.dart,
);reload
Controls how spry serve reloads during development.
Available values:
ReloadStrategy.restartReloadStrategy.hotswap
Use hotswap for targets such as Cloudflare Workers where keeping the runtime model aligned with the platform is useful.
Project layout options
routesDir
Changes the directory that Spry scans for route files.
defineSpryConfig(
routesDir: 'server/routes',
target: BuildTarget.node,
);middlewareDir
Changes the directory used for global middleware files.
defineSpryConfig(
middlewareDir: 'server/middleware',
target: BuildTarget.node,
);publicDir
Changes the static asset root. Spry checks this directory before it falls through to route handlers for GET and HEAD requests.
defineSpryConfig(
publicDir: 'static',
target: BuildTarget.dart,
);Build output options
outputDir
Controls where Spry writes generated output.
defineSpryConfig(
outputDir: 'dist/server',
target: BuildTarget.node,
);By default, Spry emits generated files into .spry/.
wranglerConfig
Lets Cloudflare targets point at a custom Wrangler config file.
defineSpryConfig(
target: BuildTarget.cloudflare,
wranglerConfig: 'deploy/wrangler.toml',
reload: ReloadStrategy.hotswap,
);Recommended mental model
- Put routing concerns in files under
routes/. - Put shared request behavior in
middleware/and_middleware.dart. - Put runtime choice in
target. - Put local dev and output behavior in
spry.config.dart.
If a setting changes how requests are matched, it probably belongs in the file tree. If it changes how the generated app runs, it belongs in config.