A well-maintained fork of the dotenv crate.
This crate is the suggested alternative for dotenv in security advisory RUSTSEC-2021-0141.
This library loads environment variables from an env file.
dotenvycrate - A well-maintained fork of thedotenvcrate.dotenvy_macrocrate - A macro for compile-time .env inspection. This is a fork ofdotenv_codegen.dotenvy-macroscrate - A runtime macro library containg theloadattribute macro.dotenvybinary that loads an env file before executing a specified command.
An env file consists of keypairs like so:
.env
HOST=foo
PORT=3000They are commonly named .env, .env.dev, .env.prod, etc., but any name can be used.
Variables can span multiple lines and also be substituted. For an explanation on substituion rules, please refer to the .env-substitution example file.
This crate contains two APIs, a non-environment-modifying API and an environment-modifying API.
Modifying calls std::env::set_var internally,
which is marked unsafe in the Rust 2024 edition. For this reason, we recommend using the non-modifying API unless
necesary.
// from a file
let loader1 = EnvLoader::with_path("./.env").sequence(EnvSequence::InputThenEnv);
let loader2 = EnvLoader::new(); // same as loader1
// from a reader
let s = "HOST=foo\nPORT=3000";
let str_loader = EnvLoader::with_reader(Cursor::new(s));
// will load from the env file, override exiting values in the program environment
let overriding_loader = EnvLoader::new().sequence(EnvSequence::EnvThenInput);Load constuction is infallible. I/O is derred until load or load_and_modify is called.
This is to allow support configurations such as dev/prod and
optional loading.
use dotenvy::{EnvLoader};
use std::{error, env};
fn main() -> Result<(), Box<dyn error::Error>> {
let env_map = EnvLoader::new().load()?;
println!("HOST={}", env_map.var("HOST")?);
Ok(())
}Sometimes, you have to modify the environment. You might spawn a child process or rely
on std::env::var to read variables.
use dotenvy::{EnvLoader};
use std::{error, env};
fn main() -> Result<(), Box<dyn error::Error>> {
let loader = EnvLoader::new();
let env_map = unsafe { loader.load_and_modify() }?;
println!("HOST={}", env_map.var("HOST")?);
println!("HOST={}", std::env::var("HOST")?);
Ok(())
}If using async, you must modify the environment before starting the async runtime.
The load attribute macro can be used to do this. To use it, enable the macros feature for the dotenvy crate.
#[dotenvy::load] // will call `load_and_modify` before the async runtime is started
#[tokio::main]
async fn main() -> Result<(), Box<dyn error::Error>> {
println!("HOST={}", env::var("HOST")?);
Ok(())
}dotenvy::load must be placed before tokio::main.
A non-macro example is here.
The dotenv! macro provided by dotenvy_macro crate can be used.
We aim to support the latest 8 rustc versions - approximately 1 year. Increasing MSRV is not considered a semver-breaking change.
The original dotenv crate has not been updated since June 26, 2020. Attempts to reach the authors and present maintainer were not successful (dotenv-rs/dotenv #74).
This fork intends to serve as the development home for the dotenv implementation in Rust.
This repo adds:
- non-modifying API
- configurable
EnvLoader - optional loading, ergonomic dev/prod handling
- reader support, such as reading from any reader that is
io::Read - more informative
Errortype, containing the file path and variable name loadattribute macro- multiline support
- more examples and docs
For a full list of changes, refer to the changelog.
Thank you very much for considering to contribute to this project! See CONTRIBUTING.md for details.
Note: Before you take the time to open a pull request, please open an issue first.
Legend has it that the Lost Maintainer will return, merging changes from dotenvy into dotenv with such thrust that all Cargo.tomls will lose one keystroke. Only then shall the Rust dotenv crateverse be united in true harmony.
Until then, this repo dutifully carries on the dotenv torch. It is actively maintained.