Expand description
Loads environment variables from .env files.
§Quick start
fn main() -> Result<(), dotenv::Error> {
dotenv::load()?;
Ok(())
}Call load near the start of your program to load a .env file
from the current working directory.
§Precedence
- Existing environment variables are never overwritten. A variable
already set in the environment takes priority over anything in
.env. - First declaration wins in
.env. If the same key appears multiple times, only the first is used. - Loading is atomic. If the file contains a parse error, no environment variable is modified, even for lines that appear before the error.
§Supported syntax
HELLO=world
HELLO="world"
HELLO='world'
HELLO='"nested"'
HELLO=world # inline comment
# full-line comment§Key names
Keys may only contain ASCII letters, digits, _, ., and -. A key may
start with any of those characters (including a digit, . or -).
§Comments
A # starts an inline comment only when it is preceded by whitespace
(K=v # comment strips the comment, but K=v#comment keeps the #).
§Whitespace
Leading whitespace on a line and whitespace around = are ignored. An
unquoted value is trimmed; whitespace inside an unquoted value is kept
(K=hello world yields hello world).
§Quotes and escapes
- Single-quoted values (
'...') are literal: no escapes are processed. - Double-quoted values (
"...") process the escape sequences\\,\',\",\$,\n,\t, and\r. Any other backslash sequence is aParseErrorKind::InvalidEscapeerror. - Backslashes in unquoted values are literal (
K=C:\pathyieldsC:\path). - A UTF-8 byte-order mark (BOM) at the very start of the file is ignored.
§Limitations
- Multi-line values are not supported.
- Variable substitution (e.g.
${FOO}) is not supported. - Export syntax (
export KEY=value) is not supported. - Only
\nand\r\nare recognised as line endings; a lone\ris not a line break. - Values may not contain a NUL byte (
\0), which cannot be placed in the process environment.
§Thread safety
load and from_path call std::env::set_var internally, which is
unsound to call while other threads are running or reading the environment.
Call them before spawning any threads (typically at the very start of
main). If you only need to inspect .env content, use parse, which
does not touch the process environment.
§Performance
.env files are configuration-sized. Because the platform setenv costs
O(n) per variable once n variables are set, loading an extremely large
number of variables is quadratic overall. Do not feed untrusted,
arbitrarily large files to load; validate them with parse first.
§Deserializing into structs with FromEnv
This crate provides a FromEnv trait (and a #[derive(FromEnv)]
proc-macro) for constructing typed structs directly from environment
variables.
§Basic usage
use dotenv::FromEnv;
#[derive(FromEnv)]
struct Config {
#[env(rename = "MY_HOST")]
host: String,
#[env(rename = "MY_PORT")]
port: u16,
}
let cfg = Config::from_env().unwrap();§Default values
Use #[env(default)] for any type that implements Default (yields the
default when the variable is not set) or #[env(default = expr)] for any
type. The environment variable is always read first; the default is only
used when it is not set.
#[derive(FromEnv)]
struct Config {
#[env(rename = "MY_HOST")]
host: String,
#[env(rename = "MY_VERBOSE", default)]
verbose: Option<bool>,
#[env(default)]
timeout: u64, // reads TIMEOUT, falls back to 0
#[env(rename = "MY_PORT", default = 8080)]
port: u16,
}Option<T> fields are always optional: an unset (or empty) variable yields
None, otherwise the value is parsed and wrapped in Some.
#[derive(FromEnv)]
struct Config {
#[env(rename = "MY_PORT")]
port: Option<u16>, // None when MY_PORT is unset or empty
}§Custom parsers
When the standard FromStr parsing is insufficient, provide a custom
parser via #[env(with = "func")]. The function may be a full path
(module::func) and must have the signature fn(&str, &str) -> Result<T, FromEnvError>:
use dotenv::{FromEnv, FromEnvError};
fn parse_port(_var: &str, val: &str) -> Result<u16, FromEnvError> {
val.parse().map_err(|e| FromEnvError::invalid("MY_PORT", val, e))
}
#[derive(FromEnv)]
struct Config {
#[env(rename = "MY_PORT", with = "parse_port")]
port: u16,
}§Nested structs
Fields whose type also implements FromEnv are automatically detected
and populated as nested structs. The parent’s field name (in
SCREAMING_SNAKE_CASE) is used as a prefix so that child fields are read
from prefixed variable names:
#[derive(FromEnv)]
struct AppConfig {
database: Database,
debug: bool, // reads DEBUG
}
#[derive(FromEnv)]
struct Database {
url: String, // reads DATABASE_URL
pool_size: u32, // reads DATABASE_POOL_SIZE
}§Custom FromEnvValue implementations
For leaf types that need special parsing logic, implement FromEnvValue
directly on your type. Types that implement FromStr get a blanket impl
automatically.
§Compile-time diagnostics
Invalid usage is reported as an ordinary compile error rather than a macro panic:
use dotenv::FromEnv;
// Tuple structs are not supported.
#[derive(FromEnv)]
struct Config(u16);use dotenv::FromEnv;
// Multiple `#[env(...)]` attributes on one field are rejected.
#[derive(FromEnv)]
struct Config {
#[env(rename = "A")]
#[env(rename = "B")]
value: u16,
}#[env(default)] without a rename reads the variable derived
from the field name and requires the field type to implement
FromEnvAuto (a built-in leaf type, or a nested FromEnv struct);
#[env(rename = "...", default)] reads the named variable via
FromEnvValue.
§Convenience function
The function from_env lets you avoid importing the trait:
let cfg: Config = dotenv::from_env().unwrap();Structs§
- Parse
Error - A parse error with the line number and kind.
Enums§
- Error
- Errors that can occur when loading a
.envfile. - From
EnvError - Error returned by
FromEnv::from_env. - Parse
Error Kind - The specific kind of parse error.
Traits§
- FromEnv
- Trait for types that can be constructed from environment variables.
- From
EnvAuto - Auto-dispatch trait for un-attributed
#[derive(FromEnv)]fields. - From
EnvValue - Trait for converting a raw env-var string into a typed value.
Functions§
- from_
env - Convenience function to load a
FromEnvtype from environment variables. - from_
path - Loads a
.envfile from an explicit path. - load
- Loads the
.envfile from the current working directory. - parse
- Parses
.envcontent into a map of key/value pairs.