flutenv 1.0.0
flutenv: ^1.0.0 copied to clipboard
A secure Flutter CLI companion that auto-injects .env variables as --dart-define arguments — keeping your secrets out of your APK.
flutenv #
Secure, zero-friction environment variable injection for Flutter. > Stop typing
--dart-defineflags. Stop bundling secrets in your APK.
Overview #
flutenv is a global Dart CLI tool that wraps the flutter command. It automatically reads your .env file and converts every key-value pair into a --dart-define argument. It is a drop-in replacement for flutter run, flutter build, and any other subcommand — with zero configuration required.
# Before flutenv
flutter run \
--dart-define=API_KEY=abc123 \
--dart-define=API_URL=https://api.example.com \
--dart-define=FEATURE_FLAG=true
# After flutenv
flutenv run
🛑 The "Plaintext Asset" Vulnerability #
Why flutter_dotenv is Unsafe for Production #
A common pattern is to use flutter_dotenv by adding your .env to pubspec.yaml assets. This approach ships your secrets as a plain text file inside your app bundle.
Since an APK or IPA is simply a ZIP archive, anyone can extract it and read your keys:
unzip build/app/outputs/flutter-apk/app-release.apk
cat assets/.env
# API_URL=https://myapi.com
# API_KEY=super_secret_key ← Exposed to the world
The flutenv Comparison #
| Feature | flutter_dotenv (Assets) |
flutenv (--dart-define) |
|---|---|---|
| Storage | Plaintext file in APK | Compiled into the Binary |
| Access | Async Runtime Load | Synchronous const |
| Security | ❌ Easy to Reverse-Engineer | ✅ Obfuscation Friendly |
| DX | Easy | Easy (with flutenv) |
The Solution: Compile-Time Injection #
Flutter provides --dart-define to inject values at build time. Values are embedded directly into the binary, making them significantly harder to extract, especially when using --obfuscate.
flutenv bridges the gap between the familiar .env file and the secure --dart-define mechanism. It reads your .env locally, but never bundles it into your app.
Installation #
# Install from pub.flutter-io.cn
dart pub global activate flutenv
Ensure the Dart pub cache binary directory is on your PATH. Dart will display a reminder if it isn't during activation.
Usage #
flutenv acts as a transparent proxy. It forwards all commands, flags, and interactive signals (like r for hot reload) to the Flutter CLI.
# Project setup & security check
flutenv init
# Standard development
flutenv run -d chrome
flutenv run --release
# Building (Secrets are injected into the compiled binary)
flutenv build apk --release --obfuscate --split-debug-info=./debug
# Testing
flutenv test
# Manual overrides on the CLI take precedence over .env
flutenv run --dart-define=API_KEY=temporary_override
flutenv init #
Run flutenv init to audit your project security:
- Adds
.envto.gitignore— Prevents committing secrets. - Scans
pubspec.yaml— Warns if.envis listed underassets:, preventing accidental leaks.
Accessing Variables in Dart #
⚠️ IMPORTANT: You must use the
constkeyword. Because variables are injected at compile-time,finalorvarwill not work and will return the default value.
// ✅ Correct
const apiKey = String.fromEnvironment('API_KEY');
const isPremium = bool.fromEnvironment('IS_PREMIUM', defaultValue: false);
// ❌ Incorrect (will not receive injected values)
final apiUrl = String.fromEnvironment('API_URL');
How It Works #
$ flutenv run -d chrome
📦 Reading .env from current directory...
🛠 Converting 5 keys to --dart-define flags...
🚀 Running: flutter run -d chrome
--dart-define=API_KEY=*** --dart-define=API_URL=*** ...
- Parses
.env(handles quotes, comments, and values with=signs). - Skips any keys already supplied manually via the command line.
- Spawns the
flutterprocess with inheritedstdio, ensuring Hot Reload works perfectly.
License #
MIT © 2026