voo_env

pub package

Secure build-time environment variable handling for Flutter with XOR obfuscation and type support. Unlike flutter_dotenv, your .env files are never exposed as runtime assets.

Features

  • Build-time code generation - Environment variables are compiled directly into Dart code
  • XOR obfuscation - Optional obfuscation makes values harder to extract from binaries
  • Type support - Parse values as String, int, double, or bool
  • Multi-environment - Support for .env.development, .env.staging, .env.production
  • Type-safe API - Generated code provides compile-time type safety

Why Not flutter_dotenv?

flutter_dotenv loads .env files from assets at runtime, meaning:

  • On web, the .env file is publicly accessible
  • On mobile, anyone can extract it from the APK/IPA
  • Your secrets are never truly hidden

voo_env solves this by generating Dart code at build time. Your .env file is only read during compilation and never bundled with your app.

Installation

dependencies:
  voo_env: ^0.1.0

dev_dependencies:
  voo_env_generator: ^0.1.0
  build_runner: ^2.4.0

Quick Start

1. Create a .env file

API_KEY=your-secret-key
BASE_URL=https://api.example.com
PORT=3000
DEBUG_MODE=true

2. Create an env class

import 'package:voo_env/voo_env.dart';

part 'env.voo_env.g.dart';

@VooEnv(obfuscate: true)
abstract class Env {
  @EnvField()
  static final String apiKey = _Env.apiKey;

  @EnvField()
  static const String baseUrl = _Env.baseUrl;

  @EnvField(type: EnvType.int)
  static const int port = _Env.port;

  @EnvField(type: EnvType.bool)
  static const bool debugMode = _Env.debugMode;
}

3. Generate code

dart run build_runner build --delete-conflicting-outputs

4. Use in your app

import 'env.dart';

void main() {
  print('API URL: ${Env.baseUrl}:${Env.port}');
  print('Debug mode: ${Env.debugMode}');

  runApp(MyApp());
}

API Reference

@VooEnv

Class annotation to enable code generation.

Parameter Type Default Description
path String .env Path to the .env file
obfuscate bool false Enable XOR obfuscation for all fields
name String? null Custom name for generated class
allowOptionalFields bool false Allow nullable fields by default
useConstantCase bool false Convert camelCase to CONSTANT_CASE

@EnvField

Field annotation to configure individual variables.

Parameter Type Default Description
name String? null Custom env var name to look up
type EnvType string Value type (string, int, double, bool)
obfuscate bool? null Override class-level obfuscation
optional bool? null Allow null if env var is missing
defaultValue Object? null Default value for optional fields

Multi-Environment Support

Create separate env files for each environment:

// For development
@VooEnv(path: '.env.development')
abstract class EnvDevelopment {
  @EnvField()
  static const String apiUrl = _EnvDevelopment.apiUrl;
}

// For production (with obfuscation)
@VooEnv(path: '.env.production', obfuscate: true)
abstract class EnvProduction {
  @EnvField()
  static final String apiUrl = _EnvProduction.apiUrl;
}

Security Notes

  • XOR obfuscation is NOT encryption - It makes extraction harder, not impossible
  • Add .env files to .gitignore - Never commit secrets to version control
  • Use backend APIs for critical secrets - The only truly secure approach

License

MIT License - see LICENSE file for details.

Libraries

voo_env
Secure build-time environment variable handling for Flutter.