Package selection guidance compiled from public package information, community data, and project usage.
flutter_dotenv is a Flutter package that enables developers to manage environment variables in their applications using a `.env` file. It simplifies configuration by loading key-value pairs from the file into the app at runtime, making it easy to handle different settings across development, testing, and production environments. The package supports all major platforms including Android, iOS, Web, macOS, Windows, and Linux. It integrates seamlessly with Flutter projects via a simple pub add command.
Use cases
Managing API keys securely
Switching between dev and prod configurations
Storing sensitive credentials
Customizing app behavior per environment
Enabling feature flags
Avoiding hardcoded values
Key features
Simple .env file integration
Cross-platform support
Runtime variable loading
Easy setup with pub add
Supports environment-specific variables
Minimal boilerplate
Suitable for
Developers managing multiple environments
Teams needing secure config management
Apps requiring dynamic configuration
Projects using CI/CD pipelines
Frontend developers working with backend APIs
Prototyping with configurable settings
Considerations
Never commit .env files to version control
Ensure .env file is included in build process
Use with caution for highly sensitive data
Verify file paths in different deployment scenarios
Handle missing variables gracefully
Be aware of case sensitivity in variable names
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
flutter_dotenv
Load configuration into your Flutter app from a .env asset file or string.
After loading, access values anywhere you import the package:
import'package:flutter_dotenv/flutter_dotenv.dart';
// Inside a function, widget, or service — not as a top-level initializerfinal apiUrl = dotenv.get('API_URL');
final retries = dotenv.getInt('MAX_RETRIES', fallback: 1);
final debug = dotenv.getBool('DEBUG', fallback: false);
If your .env file is in a subdirectory (e.g. assets/.env), pass fileName: 'assets/.env' to load() and register the same path in pubspec.yaml.
You do not need to call WidgetsFlutterBinding.ensureInitialized() — the library handles this internally when loading assets.
Tip: Add .env and any environment-specific variants (e.g. .env.staging) to your .gitignore if they should not be committed.
Security
Do not store secrets (API keys, tokens, passwords) in your .env file. Flutter assets are bundled into the app binary and can be extracted by anyone with access to the build. Values loaded by this package should be treated as public client-side configuration.
Use .env files for non-sensitive configuration only — API base URLs, feature flags, timeout values, and similar settings.
The package exports a singleton instance named dotenv. Accessing any variable before calling load() or loadFromString() throws NotInitializedError.
Use get() for required values, maybeGet() for optional values, and env[...] when direct map access is preferred.
Method
Returns
When missing
dotenv.env['NAME']
String?
null
dotenv.get('NAME')
String
Throws AssertionError
dotenv.get('NAME', fallback: 'x')
String
'x'
dotenv.maybeGet('NAME')
String?
null
dotenv.maybeGet('NAME', fallback: 'x')
String?
'x'
dotenv.env exposes the loaded key-value map directly. Treat it as read-only.
Typed getters
Parse values directly as int, double, or bool:
final retries = dotenv.getInt('MAX_RETRIES', fallback: 3);
final rate = dotenv.getDouble('RATE', fallback: 0.5);
final debug = dotenv.getBool('DEBUG', fallback: false);
All typed getters throw AssertionError if the variable is missing and no fallback is provided, and FormatException if the value cannot be parsed. getBool recognises true, false, 1, and 0 (case-insensitive).
When isOptional is true, EmptyEnvFileError is suppressed.
Value precedence
Both load() and loadFromString() call clean() first, replacing any previously loaded state. The parser keeps the first value it sees for each key. Lines are processed in this order:
Priority
Source
1 (highest)
mergeWith
2
Override files / strings
3 (lowest)
Base file / string
Note:mergeWith values cannot be overridden by the env file. If you want the .env file to take precedence over programmatic values, use override files instead of mergeWith.
State management
Member
Description
dotenv.isInitialized
true after load() or loadFromString() completes.
dotenv.clean()
Clears all loaded variables and resets isInitialized to false.
After clean(), the instance is uninitialized. Accessing values will throw NotInitializedError until the next load() or loadFromString().
Errors
Error
Thrown when
NotInitializedError
Accessing values before calling load() or loadFromString().
FileNotFoundError
The env file is not in the asset bundle (load() only).
EmptyEnvFileError
The env file or string is empty.
AssertionError
A required variable is missing and no fallback was provided.
FormatException
A typed getter can't parse the value.
.env file syntax
# Comments start with #
KEY=value
QUOTED="double quoted value"
SINGLE='single quoted value'# Variable interpolation
BASE_URL=https://api.example.com
FULL_URL=$BASE_URL/v1
ALT_URL=${BASE_URL}/v1
# Prevent interpolation with single quotes
PRICE='$9.99'# Newlines in double quotes
MULTI="line1\nline2"# The export keyword is stripped automaticallyexport EXPORTED=hello
Parsing rules:
Lines without = are ignored.
# starts a comment when it appears outside quoted values.
Double-quoted values unescape \" and expand \n to newlines, and interpolate $VAR / ${VAR}.
Single-quoted values do not interpolate variables. Escaped single quotes (\') are unescaped.
Use \$ for a literal dollar sign in unquoted or double-quoted values.
Undefined variables interpolate to an empty string.
Unquoted values are trimmed of surrounding whitespace.
If the same key appears multiple times anywhere in the processed input, the first occurrence wins (see value precedence).
Leading export keyword is stripped.
This is not a full shell parser. Complex shell expressions are not supported.
Multiple environments
Layer environment-specific values over a shared base using override files:
Override files take precedence over the base file. Register all env files as assets in pubspec.yaml.
Remote configuration
If you want to manage environment configs remotely and load them by config ID at runtime, see the companion package flutter_dotenv_remote. It also supports using the last successful config as a local fallback.
The package exports a pre-created singleton dotenv for the common case. You can also create separate instances for different configurations — each instance maintains its own independent state: