A flavor is a named configuration variant — dev, staging, prod, or any name you choose. Pass it via
--flavor <name> to zonai serve, zonai compile, and zonai build
to select the matching config file and .env file.
Naming Convention#
Config files follow a <base>.<flavor>.dart naming pattern:
lib/src/config/
db_config.dart # Base config (no flavor)
db_config.dev.dart # Loaded with --flavor dev
db_config.prod.dart # Loaded with --flavor prod
If a flavor-specific file doesn't exist, Zonai falls back to db_config.dart. Multiple files in the config directory are all compiled together.
.env Files and Flavors#
.env files work the same way:
.env # Default
.env.dev # Loaded with --flavor dev
.env.prod # Loaded with --flavor prod
How Secrets Get Baked In#
Worker code uses const String.fromEnvironment('MY_SECRET') to read a value. At compile time, Zonai passes all loaded env var values as
--define flags to dart compile exe. The resulting binary contains the literal value — the
.env file is no longer needed at runtime.
This means the dev and prod binaries have different secrets baked in. Never deploy a binary compiled with dev secrets to production.
Example Setup#
lib/src/config/db_config.dev.dart:
AppConfig main() => AppConfig(
appName: 'My App',
jwtSecret: const String.fromEnvironment('JWT_SECRET'),
passwordSecret: const String.fromEnvironment('PASSWORD_SECRET'),
baseUrl: 'http://localhost:8080',
jwtExpiresIn: const Duration(hours: 1), // short lifetime for dev
);
lib/src/config/db_config.prod.dart:
AppConfig main() => AppConfig(
appName: 'My App',
jwtSecret: const String.fromEnvironment('JWT_SECRET'),
passwordSecret: const String.fromEnvironment('PASSWORD_SECRET'),
baseUrl: 'https://api.myapp.com',
email: EmailConfig(
host: const String.fromEnvironment('SMTP_HOST'),
port: 587,
username: const String.fromEnvironment('SMTP_USER'),
password: const String.fromEnvironment('SMTP_PASS'),
from: EmailAddress(address: 'no-reply@myapp.com', name: 'My App'),
),
);
Running with a flavor:
# Dev
zonai serve --flavor dev
# Production build
zonai build --flavor prod --release
Forgetting --flavor causes the base db_config.dart to be used, which may have wrong or missing credentials. Always specify --flavor explicitly and treat the base file as a template.
