typed_env_config v0.3.0
typed_env_config
typed_env_config is a Crystal library for loading environment configurations/variables with type safety. We do so without cluttering the ENV variable.
Installation
-
Add the dependency to your
shard.yml:dependencies: typed_env_config: github: systatum/typed_env_config -
Run
shards install
Usage
First, define a configuration class. It must include TypedEnvConfig.
class AppSettings
include TypedEnvConfig
field ligo_app_cors_whitelist : String, default: ""
field ligo_undefined_key : String, default: "undefined"
end
Given the following configuration file aptly named app_settings.yml:
default: &default
outwardly_inherited: true
ligo:
app: &ligo_app
cors_whitelist: "*"
deeply_inherited: true
production:
<<: *default
ligo:
app:
<<: *ligo_app
cors_whitelist: "https://systatum.com"
development:
<<: *default
ligo:
app:
<<: *ligo_app
We can then load the configuration from a YAML file in this way:
dev_config = AppSettings.load_from_yaml_file!("spec/fixtures/app_settings.yml", "development")
dev_config.ligo_app_cors_whitelist
Easy, and type-safe!
Supported Data Types
typed_env_config supports the following data types with automatic conversion from environment variables:
String- Direct string valuesInt32- 32-bit integersInt64- 64-bit integersFloat32- 32-bit floating point numbersFloat64- 64-bit floating point numbersBool- Boolean values with intelligent conversion (see Boolean Conversion section below)
All types are automatically converted from string environment variables to their respective Crystal types. If conversion fails (e.g., setting a non-numeric string to an Int32 field), a TypedEnvConfig::LoadError will be raised with a descriptive error message.
Loading from Environment Variables
You can load configuration values from environment variables, which is particularly useful for overriding configuration values in different environments (e.g., Docker containers, Kubernetes deployments, CI/CD pipelines).
config = AppSettings.load_from_yaml_file!("config/app_settings.yml", "development")
config.load_from_env!
config.load_from_env
Note: Use load_from_env! to raise on conversion errors; use load_from_env for a non-raising boolean result.
Loading from Environment Files
This shard is self-contained and includes a built-in parser for .env-style files. Use the instance-level API to parse a file and load values into a single config instance.
Examples:
require "typed_env_config"
class AppSettings
include TypedEnvConfig
field ligo_app_cors_whitelist : String, default: ""
field small_number : Int32, default: 0
field outwardly_inherited : Bool, default: false
end
config = AppSettings.new
config.load_from_env_file!("spec/fixtures/.env_example")
puts config.ligo_app_cors_whitelist
ok = config.load_from_env_file("spec/fixtures/.env_example")
config.load_from_env!
You can also call these methods with no arguments to read the .env file in the project root:
config = AppSettings.new
config.load_from_env_file!
config.load_from_env_file
Note: Calling without an argument reads ./.env. The bang variant raises on error; the non-bang variant returns a boolean.
Notes:
- Parser supports inline comments (e.g.
KEY=val # comment), quoted values and simple escape sequences in double quotes.
How Environment Variable Loading Works
When you call load_from_env!, the library will:
- Iterate through all defined fields in your configuration class
- Generate environment variable names by converting field names to SCREAMING_SNAKE_CASE
ligo_app_cors_whitelistbecomesLIGO_APP_CORS_WHITELISTdatabase_portbecomesDATABASE_PORT
- Check if each environment variable exists and if it does:
- Convert the string value to the field's declared type
- Override the field's current value with the converted environment variable value
- Raise an error if type conversion fails (e.g., setting
"invalid"to anInt32field)
Type Conversion Examples
ENV["LIGO_APP_CORS_WHITELIST"] = "https://example.com"
ENV["DATABASE_PORT"] = "5432"
ENV["MAX_CONNECTIONS"] = "9223372036854775807"
ENV["TIMEOUT_SECONDS"] = "3.14"
ENV["PRECISION_VALUE"] = "3.141592653589793"
ENV["ENABLE_LOGGING"] = "true"
Note: These values map to the types listed above (String, Int32, Int64, Float32, Float64, Bool).
Boolean Conversion
For Bool fields, environment variable values are converted according to these rules:
Values converted to false (case-sensitive):
"0""F""false""no""NO"""(empty string)"FALSE"
All other values are converted to true, including:
"true","True","TRUE"- Any other non-empty string (e.g.,
"foo","bar")
ENV["ENABLE_DEBUG"] = "true"
ENV["ENABLE_DEBUG"] = "1"
ENV["ENABLE_DEBUG"] = "foo"
ENV["ENABLE_DEBUG"] = "false"
ENV["ENABLE_DEBUG"] = "0"
ENV["ENABLE_DEBUG"] = ""
Note: Strings "0", "F", "false", "no", "NO", "", and "FALSE" convert to false. All other non-empty strings convert to true.
Custom Environment Variable Names
By default, environment variable names are automatically generated from field names by converting them to SCREAMING_SNAKE_CASE. However, you can specify custom environment variable names using the envvar option:
class AppSettings
include TypedEnvConfig
field ligo_app_cors_whitelist : String, default: ""
field cors_whitelist : String, default: "", envvar: "LIGO_CORS_WHITELIST"
field database_port : Int32, default: 5432, envvar: "PORT"
end
Note: Use the envvar option to specify a custom environment variable name for a field.
Error Handling
When load_from_env! encounters a type conversion error, it raises a TypedEnvConfig::LoadError with a descriptive message:
class AppSettings
include TypedEnvConfig
field port : Int32, default: 3000
end
ENV["PORT"] = "invalid_number"
config = AppSettings.new
begin
config.load_from_env!
rescue TypedEnvConfig::LoadError => e
puts e.message
end
Note: load_from_env! raises TypedEnvConfig::LoadError on conversion errors with a descriptive message.
This fail-fast approach ensures that configuration errors are caught early rather than causing runtime issues later in your application.
Contributing
- Fork it (https://github.com/systatum/typed_env_config/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
Create with ⸜(。˃ ᵕ ˂ )⸝♡ at Systatum.
typed_env_config
- 0
- 0
- 0
- 0
- 0
- about 3 hours ago
- April 13, 2025
MIT License
Sun, 12 Apr 2026 10:20:47 GMT