FAQ
Frequently asked questions about Aim.
General
What is Aim?
Aim is a lightweight, modular web framework for Dart. It's designed to be simple and type-safe, with a small API surface inspired by modern frameworks like Hono.
Why Aim over other Dart frameworks?
- Simple API: Context-based API that's easy to learn, inspired by Hono
- Type-Safe: Leverages Dart's type system with custom
Variablesclasses for context variables - Modular: Independently installable middleware packages (separate packages, released together at the same version), and a database stack (
aim_postgres,aim_orm) that works withoutaim_server - Runtime-independent core: routing, middleware, and
Contextlive inaim_core; the same application code runs on the Dart VM, Cloudflare Workers, Deno-based runtimes, and Cloud Functions for Firebase (with per-runtime caveats — see Component Status) - Great DX: Built-in hot reload (
aim dev) and a dedicated testing package (aim_server_testing)
This list leaves out performance adjectives on purpose. Measured numbers, with the machine and conditions they were taken under, are on the Benchmarks page; Component Status says what has and hasn't been tested.
Is Aim production-ready?
It depends on which package. Aim is pre-1.0 (every package is at 0.4.0), and the project's own changelog calls 0.4.0 a "beta". Some packages — aim_core, aim_server, aim_postgres — are exercised by integration tests that run in CI on every push and have no known blocking issues. Others — the ORM, the CLI's database commands, the Cloudflare Workers and Deno adapters, and especially Cloud Functions for Firebase — have smaller test surfaces or explicit caveats. See Component Status for a per-package breakdown before deciding what to put in front of production traffic.
What's the relationship with Hono?
Aim's API is inspired by Hono, a popular JavaScript framework. While the API design is similar, Aim is built from the ground up for Dart with its own implementation.
Installation & Setup
What Dart version do I need?
Aim requires Dart SDK 3.13.0 or higher (every package's pubspec.yaml pins sdk: ^3.13.0).
How do I install Aim?
# Using CLI (recommended)
dart install aim_cli
aim create my_app
# Manual
dart pub add aim_serverSee the Installation guide for details.
How do I update to the latest version?
dart pub upgrade aim_serverOr update your pubspec.yaml to the latest version.
Routing
How do I define routes?
app.get('/users', handler);
app.post('/users', handler);
app.put('/users/:id', handler);
app.delete('/users/:id', handler);See Routing for details.
How do I use path parameters?
app.get('/users/:id', (c) async {
final id = c.param('id');
return c.json({'userId': id});
});How do I handle query parameters?
app.get('/search', (c) async {
final query = c.req.queryParameters['q'];
return c.json({'query': query});
});Can I use wildcards?
Yes:
app.get('/api/*', handler); // Match /api/anything
app.notFound(notFoundHandler); // Not foundMiddleware
What middleware is available?
Official middleware packages:
See Middleware Overview for all packages.
How do I create custom middleware?
Future<void> myMiddleware(Context c, Next next) async {
// Before handler
print('Before');
await next();
// After handler
print('After');
}
app.use(myMiddleware);See Middleware guide for details.
How do I skip middleware for specific routes?
app.use((c, next) async {
if (c.req.path == '/public') {
return next();
}
// Apply middleware logic
});Or use path exclusion (available in some middleware):
JwtOptions(
excludedPaths: ['/login', '/register'],
)Request & Response
How do I read JSON body?
app.post('/users', (c) async {
final body = await c.req.json();
final name = body['name'];
return c.json({'created': name});
});How do I send JSON response?
return c.json({'message': 'Hello'});
return c.json({'error': 'Not found'}, statusCode: 404);How do I handle file uploads?
Use the Multipart middleware — multipart() is an extension method on Request, not a middleware:
import 'package:aim_server/aim_server.dart';
import 'package:aim_server_multipart/aim_server_multipart.dart';
import 'package:aim_server_multipart/aim_server_multipart_io.dart';
app.post('/upload', (c) async {
final form = await c.req.multipart();
final file = form.file('document');
if (file == null) {
return c.json({'error': 'No file uploaded'}, statusCode: 400);
}
await file.saveTo('uploads/${file.filename}');
return c.json({'uploaded': file.filename});
});How do I set response headers?
app.get('/', (c) async {
c.header('X-Custom', 'value');
c.header('Cache-Control', 'no-cache');
return c.json({'data': 'value'});
});Authentication
How do I implement authentication?
Use JWT Auth or Basic Auth:
import 'package:aim_server_jwt/aim_server_jwt.dart';
final app = Aim<JwtVariables>(
variablesFactory: () => JwtVariables.create(
JwtOptions(
algorithm: HS256(
secretKey: SecretKey(secret: 'at-least-32-characters-long-secret-key'),
),
excludedPaths: ['/login'],
),
),
);
app.use(jwt());How do I protect specific routes?
app.use() registers middleware that runs for every request, regardless of where the call appears relative to the routes it sits next to — there is no Express-style "only affects routes registered after this point". Use JwtOptions.excludedPaths (or the equivalent option on other auth middleware) to name the routes that should skip authentication:
final app = Aim<JwtVariables>(
variablesFactory: () => JwtVariables.create(
JwtOptions(
algorithm: HS256(secretKey: SecretKey(secret: '...')),
excludedPaths: ['/login'],
),
),
);
app.use(jwt());
app.post('/login', loginHandler); // excluded, runs without a token
app.get('/dashboard', dashboardHandler); // requires a valid tokenCan I use session-based auth?
Yes, use the Cookie extensions:
import 'package:aim_server_cookie/aim_server_cookie.dart';
app.post('/login', (c) async {
c.setCookie(
'session_id',
sessionId,
options: CookieOptions(
httpOnly: true,
secure: true,
maxAge: Duration(days: 7),
),
);
return c.json({'success': true});
});Development
How do I enable hot reload?
Use the Aim CLI:
aim devHow do I debug my application?
Use Dart's built-in debugger with VS Code or IntelliJ:
- Set breakpoints in your code
- Run with debugger (F5 in VS Code)
- Use the debug console
For logging, use the Logger middleware.
How do I run tests?
dart testSee the Testing guide for details.
Deployment
How do I deploy to production?
Build your application:
bash# Build with default settings (output: build/server) aim build # Custom entry point and output aim build --entry bin/server.dart --output my-serverDeploy the binary to your server
Run with environment variables:
bashENV=production JWT_SECRET=xxx ./build/server
Does Aim support serverless?
Yes, for three targets, at different maturity levels (see Component Status for what's verified in CI):
- Cloudflare Workers (
aim_workers) — Beta, integration-tested against a realwrangler dev. - Supabase Edge Functions and other Deno runtimes (
aim_deno) — Beta, verified against a local Supabase stack and, for HTTP routing only, a real deployed Supabase function. - Cloud Functions for Firebase (
aim_functions) — Experimental, inheritingfirebase_functions's own experimental Dart support.
The same application code runs across these and the Dart VM through aim_core's runtime-independent design; each runtime page above covers its specific setup and limitations (for example, aim_postgres and the ORM need dart:io and cannot run in a Worker or Deno wasm build).
How do I enable HTTPS?
final context = SecurityContext()
..useCertificateChain('server_chain.pem')
..usePrivateKey('server_key.pem');
await app.serve(
host: InternetAddress.anyIPv4,
port: 443,
securityContext: context,
);How do I configure CORS for production?
import 'package:aim_server_cors/aim_server_cors.dart';
app.use(cors(CorsOptions(
origin: ['https://example.com', 'https://app.example.com'],
credentials: true,
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
)));See CORS guide for details.
Performance
How fast is Aim?
See the Benchmarks page for measured numbers and the conditions they were taken under. Routing is a linear scan of registered routes with the first match winning; for applications with a very large number of routes, that is worth keeping in mind. In the measured run, the routes_100 scenario (100 static routes, last one requested) was about 1% below the plaintext scenario's median, within run-to-run noise.
How do I optimize performance?
- Use connection pooling for databases
- Implement caching where appropriate
- Use async operations efficiently
- Profile with Dart DevTools
See Best Practices for optimization tips.
Can I use multiple isolates?
Yes, you can run multiple instances across isolates:
void main() async {
final cores = Platform.numberOfProcessors;
for (var i = 0; i < cores; i++) {
await Isolate.spawn(startServer, i);
}
}
void startServer(int id) async {
final app = Aim();
// Configure app...
await app.serve(host: InternetAddress.anyIPv4, port: 8080 + id);
}Troubleshooting
My middleware isn't running
Check the order - middleware runs in the order it's added:
app.use(logger()); // Runs first
app.use(cors()); // Runs second
app.use(jwt()); // Runs thirdHeaders aren't being set
Make sure you set headers before returning the response:
// ✅ Good
c.header('X-Version', '1.0');
return c.json({...});
// ❌ Bad
const response = c.json({...});
c.header('X-Version', '1.0'); // Too late!
return response;Port already in use
Another process is using the port. Kill it or use a different port:
# Find process
lsof -i :8080
# Kill process
kill -9 <PID>
# Or use different port
await app.serve(host: InternetAddress.anyIPv4, port: 3000);Community
How do I get help?
- Check this FAQ
- Read the documentation
- Open an issue on GitHub
How do I contribute?
There is no CONTRIBUTING.md yet. Open an issue or a pull request on GitHub to start a conversation before sending a large change.
Where can I report bugs?
Report bugs on GitHub Issues.
Next Steps
- Read the Best Practices
- Explore Testing
- Check out Middleware
