Repository navigation
Releases: ikelaiah/dotenv-fp
Release list
🌿 dotenv-fp v1.2.1
Release Date: July 21, 2026
🚀 Overview
Version 1.2.1 is a documentation and example-reliability patch release. It
makes the runnable projects under examples/ the single
source of truth, brings every project up to the current safe usage guidance,
and adds one cross-platform command for building all examples into
examples-bin/.
The dotenv-fp API is unchanged from v1.2.0.
🌱 One Clear Beginner Path
Beginners should start with
examples/hello-dotenv/hello_dotenv.pas.
The new examples/README.md then provides an explicit
learning order:
hello-dotenv— strict startup and typed validationbasic— arrays, interpolation, and redacted diagnosticsadvanced— prefixing, layered files, and in-memory configurationenvironment-aware—.env.{environment}loadinginteractive-setup— prompts, validation, saving, and template generation
docs/examples.md is now a catalog linking to these projects
instead of a second collection of standalone programs that could drift out of
sync.
🔨 Reproducible Example Builds
Build all five Lazarus projects on Linux or macOS:
bash ./build-examples.shBuild them on Windows PowerShell:
./build-examples.ps1Both scripts:
- Discover canonical
examples/*/*.lpiprojects one directory deep - Build every project in Lazarus Release mode
- Place executables directly under
examples-bin/ - Keep compiler units under
examples-bin/units/<example>/ - Fail when a project or expected executable is missing
- Clean the generated output directory before rebuilding
The generated examples-bin/ directory is ignored by Git.
🛡️ Safer Runnable Examples
- Basic and advanced configuration keys are namespaced to avoid common process
environment collisions - The basic example reports whether a secret exists and uses redacted
diagnostics without printing the secret - The advanced example no longer prints database URLs or other potentially
credential-bearing values - The interactive setup confirms that a database URL is configured without
displaying it - The environment-aware example uses non-secret values in a unique temporary
directory and removes its files on exit - Previously committed runtime
.envfiles were removed; safe templates use
.env.examplenames
🔄 Continuous Integration
Windows CI runs build-examples.ps1, and Linux CI runs build-examples.sh.
Both platforms smoke-test all five examples. CI supplies blank input to the
interactive setup, verifies that .env and .env.example are created, and
checks that the generated template contains no configured values.
✅ Validation
- FPC 3.2.2: 121 tests, 0 errors, 0 failures
- Lazarus package v1.2.1 build: pass
- Windows PowerShell example build script: all five projects pass
- POSIX shell script syntax check: pass
- Newcomer hostile-environment smoke test: pass
- All five example runtime smoke tests: pass
- Markdown links and code fences: pass
git diff --check: pass
🔀 Migration from v1.2.0
No application code changes are required. The public API and runtime behavior
are unchanged.
Repository contributors should use the new build scripts instead of invoking
each example project manually. Built executables now live in examples-bin/
when using the documented workflow.
🔐 Security Reminder
Commit .env.example templates only. Keep real .env files ignored, avoid
printing credential-bearing configuration, and use a dedicated secret manager
for production credentials.
Thank you for using dotenv-fp! 🎉
For issues or suggestions, visit the
dotenv-fp repository.
🌿dotenv-fp v1.2.0
Release Date: July 20, 2026
🚀 Overview
Version 1.2.0 focuses on reliable application startup, safer diagnostics, and dependable .env file round trips. It adds strict loading with actionable errors, aggregate typed schema validation, atomic saving, secret redaction, a five-minute newcomer example, and Windows/Linux continuous integration.
Existing applications can continue using the permissive Load() API. The stricter behavior is opt-in through LoadRequired() and the schema validation methods.
✨ New Features
1. 🚨 Strict Dotenv Loading
Method: LoadRequired(const APath: string = '.env'): Boolean
Strictly loads a dotenv file and raises an actionable exception when the file is missing or malformed.
Key Benefits:
- Reports the absolute file path
- Identifies the line number and offending key or entry
- Explains why parsing failed
- Keeps the existing permissive
Load()behavior available
Usage:
try
Env.LoadRequired('.env');
except
on E: EDotEnvException do
WriteLn(E.Message);
end;Depending on the failure, LoadRequired() raises EDotEnvFileNotFound, EDotEnvParseError, or EDotEnvException.
2. 🧭 Aggregate Typed Schema Validation
Types and methods:
TDotEnvSchemaItemValidateSchema()ValidateSchemaRequired()
Validate all required configuration values and their expected types in one pass. Supported types are string, integer, boolean, and float.
Key Benefits:
- Reports all missing and invalid values together
- Avoids repeated fix-and-restart cycles during application startup
- Provides both a Boolean API and an exception-based API
- Uses the same typed rules as dotenv-fp's required getters
Usage:
Env.ValidateSchemaRequired([
TDotEnvSchemaItem.Create('DATABASE_URL'),
TDotEnvSchemaItem.Create('APP_PORT', dvkInteger),
TDotEnvSchemaItem.Create('APP_DEBUG', dvkBoolean),
TDotEnvSchemaItem.Create('REQUEST_TIMEOUT', dvkFloat)
]);ValidateSchemaRequired() raises one EDotEnvValidationError containing every schema problem.
3. 🛡️ Redacted Diagnostics
Method: ToRedactedString: string
Produces diagnostic output while replacing values for likely secret keys with [REDACTED].
WriteLn(Env.ToRedactedString);Verbose loading now applies the same protection so common password, token, secret, and API-key values are not printed in plaintext.
Redaction is a diagnostic safeguard, not a substitute for keeping real secrets out of source control and application logs.
4. 👋 Five-Minute Newcomer Example
A new examples/hello-dotenv/ Lazarus project demonstrates the recommended startup flow:
- Strictly load
.env - Validate all required settings
- Read typed values
- Display actionable errors
The example uses namespaced APP_PORT and APP_DEBUG keys so unrelated process variables such as PORT and DEBUG cannot unexpectedly override it. A root .env.example provides a safe configuration template.
🔧 Reliability and Safety Improvements
💾 Atomic, Escaped Saving
Save() now:
- Quotes and escapes every value
- Writes to a same-directory temporary file
- Atomically replaces the destination
- Preserves spaces,
#, quotes, backslashes, control characters, and interpolation-like text across save/load round trips
Env.SetToEnv('MESSAGE', 'A value with spaces and # characters');
Env.Save('.env');
Env.LoadRequired('.env');🧩 Parsing and Type Safety
- Multiline double-quoted values no longer truncate at escaped quotes
- Single-quoted values are treated as literals and do not interpolate variables
- Empty
${}interpolation resolves to an empty string instead of querying the operating system with an empty variable name - The empty-interpolation fix prevents hidden Windows drive-current-directory entries, such as
::=::\, from leaking into parsed values GetBoolRequired()now rejects unrecognized Boolean values instead of silently treating them asFalse
🧭 Clearer Environment Semantics
Documentation now distinguishes dotenv-fp's in-memory values from operating-system environment variables. SetToEnv() updates the current TDotEnv instance; it does not modify the parent process environment.
🔄 Continuous Integration
The project now validates every change on both Windows and Linux. CI builds and checks:
- The Lazarus package
- The complete FPCUnit test suite
- All five Lazarus examples
- The newcomer example with hostile generic
PORTandDEBUGprocess variables
✅ Testing
- ✅ FPC 3.2.2: 121 tests, 0 errors, 0 failures
- ✅ Lazarus package build passes
- ✅ All five Lazarus examples build and run successfully
- ✅ Newcomer smoke test passes with
PORT=not-an-integerandDEBUG=release - ✅ Windows and Linux CI coverage
- ✅ No new runtime dependencies
📚 Documentation Updates
- ✅ README updated with strict loading, schema validation, safe saving, and redacted diagnostics
- ✅ API reference updated for the new types, methods, and exceptions
- ✅ Getting-started and configuration guides updated
- ✅ Root
.env.exampleadded - ✅ Package metadata and changelog updated for version 1.2.0
🔀 Migration Guide
From v1.1.0 to v1.2.0
No APIs were removed, and existing Load() calls remain permissive. Existing applications can upgrade without changing their loading code.
For stricter application startup, replace:
Env.Load('.env');with:
Env.LoadRequired('.env');
Env.ValidateSchemaRequired([
TDotEnvSchemaItem.Create('DATABASE_URL'),
TDotEnvSchemaItem.Create('APP_PORT', dvkInteger),
TDotEnvSchemaItem.Create('APP_DEBUG', dvkBoolean)
]);Review these behavior refinements when upgrading:
GetBoolRequired()now raises an error for values other thantrue,false,yes,no,1,0,on, oroff- Single-quoted values no longer interpolate; use double quotes when interpolation is intended
- Files written by
Save()are consistently quoted and escaped, although loading them returns the original values
🔐 Security Recommendations
- Never commit
.envfiles containing real credentials - Commit
.env.examplewith safe placeholders or empty values - Keep
.env*ignored except for approved example files - Prefer
ToRedactedString()over raw values when troubleshooting - Use a dedicated secret manager for production credentials
Thank you for using dotenv-fp! 🎉
For issues or suggestions, please visit: https://github.com/ikelaiah/dotenv-fp
🌿 dotenv-fp v1.1.0
Overview
Version 1.1.0 adds four practical, easy-to-use features that enhance the dotenv-fp library with minimal cognitive burden for both new and experienced developers. All features follow industry-standard patterns familiar to developers from other ecosystems.
New Features
1. 🌍 Environment-Aware Loading
Method: LoadForEnvironment(const AEnvironment: string = ''): Boolean
Automatically loads base configuration from .env, then environment-specific overrides from .env.{environment}.
Key Benefits:
- Industry-standard pattern (used in Node.js, Rails, Django, etc.)
- Auto-detects environment from
APP_ENVorNODE_ENVsystem variables - Zero cognitive burden - developers already know this pattern
- Simplifies managing dev/staging/production configs
Usage:
// Load for specific environment
Env.LoadForEnvironment('production'); // Loads .env + .env.production
// Auto-detect from system environment
Env.LoadForEnvironment(); // Uses APP_ENV or NODE_ENV2. 💾 Save to File
Method: Save(const APath: string = '.env'): Boolean
Saves all loaded environment variables to a .env file.
Key Benefits:
- Generate
.envfiles programmatically - Persist runtime configuration changes
- Useful for installers and setup scripts
- Simple API - just one method call
Usage:
Env := TDotEnv.Create;
Env.SetToEnv('DATABASE_URL', 'postgres://localhost/mydb');
Env.SetToEnv('PORT', '3000');
Env.Save('.env'); // Write to disk3. 💬 Interactive Prompts
Method: GetOrPrompt(const AKey, APrompt: string; const ADefault: string = ''): string
Gets a value by key, or prompts the user if the value is missing.
Key Benefits:
- Perfect for first-run setup scripts
- Interactive configuration wizards
- No need for separate input handling code
- Stored value can be saved with
Save()
Usage:
DbUrl := Env.GetOrPrompt('DATABASE_URL',
'Enter database URL',
'postgres://localhost/mydb');
// If DATABASE_URL exists, returns it
// If missing, prompts user and stores the answer4. 📋 Generate Example Files
Method: GenerateExample(const ASourcePath: string = '.env'; const ADestPath: string = '.env.example'): Boolean
Creates a .env.example file from a source .env file, preserving keys and comments but removing values.
Key Benefits:
- Standard Git best practice - commit
.env.example, not.env - Documents required configuration for team members
- Preserves file structure and comments
- One command to generate template
Usage:
Env.GenerateExample('.env', '.env.example');Input (.env):
# Database config
DATABASE_URL=postgres://localhost/mydb
PORT=3000Output (.env.example):
# Database config
DATABASE_URL=
PORT=Examples
Two new comprehensive examples added as Lazarus projects:
-
examples/interactive-setup/ - Interactive setup wizard using
GetOrPrompt()andSave()- Includes
.lpiproject file and comprehensive README
- Includes
-
examples/environment-aware/ - Multi-environment loading with
LoadForEnvironment()- Includes
.lpiproject file and comprehensive README
- Includes
⚠️ Important Security Note for Examples
The example programs create files with NO actual secrets - only demonstration values like DEBUG=true or PORT=3000. They are meant to show the loading pattern, not production security practices.
Real-world security best practices:
- NEVER commit files with actual secrets to Git, even if named
.env.production - Use
.env.examplefiles (empty values) for version control - Add
.env*to.gitignore(except.env.example) - Store real secrets in:
- Environment variables (set by hosting platform: Heroku, AWS, Azure, etc.)
- Secret management tools (AWS Secrets Manager, HashiCorp Vault, etc.)
- Local
.envfiles (NOT committed to Git)
Testing
- ✅ All 96 existing tests pass
- ✅ Compiles cleanly with FPC 3.2.2+
- ✅ No breaking changes to existing API
- ✅ Zero new dependencies
Documentation Updates
- ✅ README.md updated with new features
- ✅ CHANGELOG.md updated
- ✅ Version number bumped to 1.1.0
- ✅ Code comments added for all new methods
- ✅ Example programs created
Migration Guide
From v1.0.0 to v1.1.0: No breaking changes! All existing code continues to work.
Simply update your library file and start using the new features:
// Old way still works
Env := TDotEnv.Create;
Env.Load('.env');
// New way - more convenient
Env := TDotEnv.Create;
Env.LoadForEnvironment('production');Future Compatibility
All new features are designed to be:
- ✅ Simple and intuitive
- ✅ Following established patterns
- ✅ Easy to understand
- ✅ Well-documented
- ✅ Tested and reliable
Developer Experience
Cognitive load: Minimal - all features use familiar patterns from other ecosystems
Learning curve: Near zero for developers familiar with Node.js, Python, Ruby, or similar environments
What's Next?
Version 1.1.0 focuses on practical, commonly-needed features.
Future versions may include:
- Schema validation with type checking
- File watching and auto-reload
- Encryption support for sensitive values
- Export to other formats (JSON, XML, INI)
Thank you for using dotenv-fp! 🎉
For issues or suggestions, please visit: https://github.com/ikelaiah/dotenv-fp
🌿 dotenv-fp – Initial Release
A feature-rich dotenv library for Free Pascal 3.2.2+
We're excited to announce the first stable release of dotenv-fp, a powerful and easy-to-use library for loading environment variables from .env files in Free Pascal applications!
🌟 Highlights
- Zero Dependencies → Uses only standard FPC units
- Zero Memory Leaks → Advanced records mean no manual
Freecalls - Type-Safe → Built-in type conversion with
GetInt(),GetBool(),GetFloat(),GetArray() - Production Ready → 96 comprehensive tests, all passing
- Cross-Platform → Works on Windows, Linux, and macOS
✨ Features
Core Functionality
- 📁 Load environment variables from
.envfiles - 🔗 Variable interpolation with
${VAR}or$VARsyntax - 📝 Multi-line value support
- 🎯 Quoted values (single quotes, double quotes, or unquoted)
- 💬 Comment support with
#(line or inline) - 🐚 Shell-compatible
exportprefix
Advanced Features
- 🔒 Type-safe getters with automatic conversion
- ⚡ Default value fallbacks for missing keys
- ✅ Built-in validation for required variables
- 📚 Multiple file loading (
.env,.env.local,.env.production, etc.) - 🏷️ Key prefixing support (e.g., add
APP_prefix to all keys)
📦 Installation
// 1. Copy src/DotEnv.pas to your project
// 2. Add to your uses clause
uses
DotEnv;
// 3. Load your .env file
var
Env: TDotEnv;
begin
Env := TDotEnv.Create('.env');
WriteLn(Env.Get('DATABASE_URL'));
end;📚 Documentation
🔧 Requirements
- Free Pascal 3.2.2 or higher
- Compatible with Lazarus 4.0+
- Supports Windows, Linux, and macOS
🙏 Acknowledgments
Inspired by python-dotenv, bringing the convenience of dotenv to the Pascal ecosystem!
📝 License
MIT License - see LICENSE for details
Full Changelog: https://github.com/ikelaiah/dotenv-fp/blob/main/CHANGELOG.md