This page lists the public API exposed by the env module. For normal application code, include the public module header and use the symbols from the vix::env namespace.
#include <vix/env.hpp>For examples that print output or diagnostics, include:
#include <vix/print.hpp>All Env APIs live in the vix::env namespace.
vix::env::get("APP_ENV");
vix::env::load_file(".env");
vix::env::load_into_process(".env");EnvErrorCode describes environment-specific failures before they are mapped into the generic Vix error system.
enum class EnvErrorCode
{
None = 0,
EmptyKey,
InvalidKey,
EmptyPath,
InvalidPath,
FileNotFound,
FileReadFailed,
ParseFailed,
InvalidLine,
InvalidValue,
MissingValue,
UnsupportedOperation,
AlreadyExists,
NotFound
};| Code | Meaning |
|---|---|
None |
No environment error. |
EmptyKey |
The environment key is empty. |
InvalidKey |
The key does not follow the accepted environment key format. |
EmptyPath |
A required path or path component is empty. |
InvalidPath |
A path is invalid for the requested operation. |
FileNotFound |
A dotenv file could not be opened. |
FileReadFailed |
A dotenv file was opened but could not be read correctly. |
ParseFailed |
Full dotenv content failed to parse. |
InvalidLine |
A dotenv line is syntactically invalid. |
InvalidValue |
A value cannot be parsed or used as requested. |
MissingValue |
A value is empty when empty values are not allowed. |
UnsupportedOperation |
A platform environment operation failed or is unsupported. |
AlreadyExists |
A value already exists where duplication is not allowed. |
NotFound |
A requested environment variable or resource was not found. |
vix::error::ErrorCategory env_error_category() noexcept;
vix::error::ErrorCode to_error_code(EnvErrorCode code) noexcept;
const char *to_string(EnvErrorCode code) noexcept;
vix::error::Error make_env_error(EnvErrorCode code, std::string message);env_error_category() returns the default error category for the module. to_error_code() maps an EnvErrorCode to the generic vix::error::ErrorCode used across Vix. to_string() returns a stable text name for an Env error code. make_env_error() builds a structured Vix error from an Env error code and a human-readable message.
#include <vix/env.hpp>
#include <vix/print.hpp>
int main()
{
auto error = vix::env::make_env_error(
vix::env::EnvErrorCode::InvalidKey,
"environment key is invalid");
vix::print("error:", error.message());
return 0;
}The module uses vix::error::Result<T> for APIs that return a value and may fail.
using EnvStringResult = vix::error::Result<std::string>;
using EnvBoolResult = vix::error::Result<bool>;
using EnvIntResult = vix::error::Result<int>;
using EnvUintResult = vix::error::Result<unsigned>;
using EnvDoubleResult = vix::error::Result<double>;
using EnvEntryResult = vix::error::Result<EnvEntry>;
using EnvEntryListResult = vix::error::Result<EnvEntryList>;
using EnvMapResult = vix::error::Result<EnvMap>;These aliases make function signatures easier to read while keeping error handling consistent with the rest of Vix.
EnvEntry represents one parsed key-value pair from dotenv content.
struct EnvEntry
{
std::string key;
std::string value;
};A blank line or comment line parsed with parse_line() succeeds with an empty EnvEntry.
EnvMap stores parsed values by key.
using EnvMap = std::unordered_map<std::string, std::string>;When a key appears more than once in parsed content, the map stores the last value for that key.
EnvEntryList stores parsed entries in their original order.
using EnvEntryList = std::vector<EnvEntry>;This is useful for tools that need to inspect or preserve the order of a dotenv file.
EnvFile is the in-memory representation of a parsed dotenv file.
struct EnvFile
{
std::string path;
EnvEntryList entries;
EnvMap values;
};| Field | Purpose |
|---|---|
path |
Original file path associated with the parsed content. |
entries |
Ordered parsed entries. |
values |
Key-value map of final parsed values. |
#include <vix/env.hpp>
#include <vix/print.hpp>
int main()
{
auto file = vix::env::load_file(".env");
if (!file.ok())
{
vix::print("failed to load .env:", file.error().message());
return 1;
}
vix::print("path:", file.value().path);
vix::print("entries:", file.value().entries.size());
return 0;
}using EnvFileResult = vix::error::Result<EnvFile>;This is the standard result type for functions that load or parse a dotenv file.
EnvOptions contains common settings used by process environment operations and dotenv parsing.
struct EnvOptions
{
bool trim_whitespace{true};
bool case_insensitive_bools{true};
bool allow_empty_values{true};
bool overwrite_existing{true};
bool require_existing{false};
};| Field | Default | Purpose |
|---|---|---|
trim_whitespace |
true |
Trim leading and trailing whitespace when parsing. |
case_insensitive_bools |
true |
Boolean parsing is case-insensitive. |
allow_empty_values |
true |
Allow entries such as KEY=. |
overwrite_existing |
true |
Allow process injection to overwrite existing variables. |
require_existing |
false |
Common strictness option for workflows that require existing variables. |
EnvFileMode controls whether file resolution targets one file or a layered set of files.
enum class EnvFileMode
{
Single,
Layered
};Single resolves the primary file named by filename. Layered resolves the selected base, local, environment-specific, and environment-local files.
EnvFileOptions controls dotenv file resolution, parsing, and loading.
struct EnvFileOptions
{
EnvOptions env{};
vix::path::PathOptions path{};
std::string base_dir{"."};
std::string filename{".env"};
std::string environment_name{};
EnvFileMode mode{EnvFileMode::Single};
bool load_base_file{true};
bool load_local_file{false};
bool load_environment_file{false};
bool load_environment_local_file{false};
bool ignore_missing_files{true};
bool ignore_blank_lines{true};
bool ignore_comments{true};
bool strip_quotes{true};
};| Field | Default | Purpose |
|---|---|---|
env |
{} |
Common environment options. |
path |
{} |
Path options used when resolving dotenv file paths. |
base_dir |
"." |
Base directory used to resolve files. |
filename |
".env" |
Base dotenv filename. |
environment_name |
"" |
Environment suffix such as production or test. |
mode |
EnvFileMode::Single |
Single-file or layered resolution mode. |
load_base_file |
true |
Include the base file, such as .env. |
load_local_file |
false |
Include the local file, such as .env.local. |
load_environment_file |
false |
Include the environment-specific file, such as .env.production. |
load_environment_local_file |
false |
Include the environment-local file, such as .env.production.local. |
ignore_missing_files |
true |
Skip missing selected files during layered loading. |
ignore_blank_lines |
true |
Ignore blank lines while parsing. |
ignore_comments |
true |
Ignore comment lines beginning with #. |
strip_quotes |
true |
Remove matching quotes around parsed values. |
These functions read and modify the current process environment.
bool has(std::string_view key) noexcept;
EnvStringResult get(std::string_view key);
std::string get_or(std::string_view key, std::string_view default_value = "");
vix::error::Error set(std::string_view key, std::string_view value, bool overwrite = true) noexcept;
vix::error::Error unset(std::string_view key) noexcept;bool has(std::string_view key) noexcept;Returns true when the variable exists in the current process environment. Empty or invalid keys return false.
if (vix::env::has("DATABASE_URL"))
{
vix::print("database configuration is present");
}EnvStringResult get(std::string_view key);Reads a variable as a string. The result fails when the key is empty, the key is invalid, or the variable is not found.
auto value = vix::env::get("APP_ENV");
if (!value.ok())
{
vix::print("APP_ENV is missing:", value.error().message());
return 1;
}
vix::print("APP_ENV:", value.value());std::string get_or(std::string_view key, std::string_view default_value = "");Reads a variable as a string and returns the provided default when the value cannot be read.
std::string app_env = vix::env::get_or("APP_ENV", "development");Use get_or() for optional values where falling back is the intended behavior.
vix::error::Error set(
std::string_view key,
std::string_view value,
bool overwrite = true) noexcept;Sets a variable in the current process environment.
auto error = vix::env::set("APP_ENV", "test");
if (error)
{
vix::print("failed to set APP_ENV:", error.message());
return 1;
}When overwrite is false, an existing value is preserved.
vix::error::Error unset(std::string_view key) noexcept;Removes a variable from the current process environment.
auto error = vix::env::unset("APP_ENV");
if (error)
{
vix::print("failed to unset APP_ENV:", error.message());
return 1;
}Removing a missing variable succeeds. Invalid keys still return an error.
Typed readers read from the current process environment and parse the string value into the requested type.
EnvBoolResult get_bool(std::string_view key);
EnvIntResult get_int(std::string_view key);
EnvUintResult get_uint(std::string_view key);
EnvDoubleResult get_double(std::string_view key);EnvBoolResult get_bool(std::string_view key);Reads a variable as a boolean. Accepted truthy values are 1, true, yes, and on. Accepted falsy values are 0, false, no, and off.
auto debug = vix::env::get_bool("DEBUG");
if (!debug.ok())
{
vix::print("DEBUG must be a boolean:", debug.error().message());
return 1;
}
vix::print("debug:", debug.value());EnvIntResult get_int(std::string_view key);Reads a variable as a signed base-10 integer.
auto port = vix::env::get_int("PORT");
if (!port.ok())
{
vix::print("PORT must be an integer:", port.error().message());
return 1;
}EnvUintResult get_uint(std::string_view key);Reads a variable as an unsigned base-10 integer.
auto workers = vix::env::get_uint("WORKERS");
if (!workers.ok())
{
vix::print("WORKERS must be an unsigned integer:", workers.error().message());
return 1;
}EnvDoubleResult get_double(std::string_view key);Reads a variable as a floating-point value.
auto timeout = vix::env::get_double("TIMEOUT_SECONDS");
if (!timeout.ok())
{
vix::print("TIMEOUT_SECONDS must be a number:", timeout.error().message());
return 1;
}Parsing functions convert dotenv text into structured data. They do not modify the process environment.
EnvEntryResult parse_line(std::string_view line, const EnvFileOptions &options = {});
EnvFileResult parse_content(
std::string_view content,
std::string_view path = {},
const EnvFileOptions &options = {});EnvEntryResult parse_line(
std::string_view line,
const EnvFileOptions &options = {});Parses one dotenv line into an EnvEntry.
Supported forms include:
KEY=VALUE
KEY = VALUE
export KEY=VALUEBlank lines and comment lines succeed with an empty entry.
auto entry = vix::env::parse_line("APP_ENV=production");
if (!entry.ok())
{
vix::print("failed to parse line:", entry.error().message());
return 1;
}
vix::print("key:", entry.value().key);
vix::print("value:", entry.value().value);EnvFileResult parse_content(
std::string_view content,
std::string_view path = {},
const EnvFileOptions &options = {});Parses complete dotenv content into an EnvFile.
auto file = vix::env::parse_content(
"APP_ENV=test\n"
"PORT=9000\n",
".env.test");
if (!file.ok())
{
vix::print("failed to parse content:", file.error().message());
return 1;
}
vix::print("entries:", file.value().entries.size());When parsing fails, the returned error message includes the line number.
These functions resolve dotenv file paths from EnvFileOptions.
using EnvPathListResult = vix::error::Result<std::vector<std::string>>;
vix::error::Result<std::string> resolve_env_file(
const EnvFileOptions &options = {});
EnvPathListResult resolve_env_files(
const EnvFileOptions &options = {});vix::error::Result<std::string> resolve_env_file(
const EnvFileOptions &options = {});Resolves the primary dotenv file path from base_dir and filename.
vix::env::EnvFileOptions options;
options.base_dir = ".";
options.filename = ".env";
auto path = vix::env::resolve_env_file(options);
if (!path.ok())
{
vix::print("failed to resolve .env path:", path.error().message());
return 1;
}
vix::print("path:", path.value());EnvPathListResult resolve_env_files(
const EnvFileOptions &options = {});Resolves all selected dotenv file paths. In single mode, it returns one path. In layered mode, it may return paths such as .env, .env.local, .env.production, and .env.production.local.
vix::env::EnvFileOptions options;
options.mode = vix::env::EnvFileMode::Layered;
options.environment_name = "production";
options.load_base_file = true;
options.load_local_file = true;
options.load_environment_file = true;
options.load_environment_local_file = true;
auto paths = vix::env::resolve_env_files(options);
if (!paths.ok())
{
vix::print("failed to resolve environment files:", paths.error().message());
return 1;
}
for (const auto &path : paths.value())
{
vix::print(path);
}File loading functions read dotenv files from disk and return parsed data.
EnvFileResult load_file(
std::string_view path,
const EnvFileOptions &options = {});
using EnvFileListResult = vix::error::Result<std::vector<EnvFile>>;
EnvFileListResult load_layered(
const EnvFileOptions &options = {});EnvFileResult load_file(
std::string_view path,
const EnvFileOptions &options = {});Loads and parses one explicit dotenv file.
auto file = vix::env::load_file(".env");
if (!file.ok())
{
vix::print("failed to load .env:", file.error().message());
return 1;
}
vix::print("entries:", file.value().entries.size());EnvFileListResult load_layered(
const EnvFileOptions &options = {});Resolves and loads selected dotenv layers according to EnvFileOptions.
vix::env::EnvFileOptions options;
options.mode = vix::env::EnvFileMode::Layered;
options.environment_name = "production";
options.load_base_file = true;
options.load_local_file = true;
options.load_environment_file = true;
options.load_environment_local_file = true;
options.ignore_missing_files = true;
auto files = vix::env::load_layered(options);
if (!files.ok())
{
vix::print("failed to load layered environment:", files.error().message());
return 1;
}
vix::print("loaded files:", files.value().size());load_layered() returns parsed files. It does not inject values into the current process environment.
Process injection loads parsed dotenv values into the current process environment.
vix::error::Error load_into_process(
std::string_view path,
const EnvFileOptions &options = {});
vix::error::Error load_layered_into_process(
const EnvFileOptions &options = {});vix::error::Error load_into_process(
std::string_view path,
const EnvFileOptions &options = {});Loads one dotenv file and injects its parsed entries into the current process environment.
auto error = vix::env::load_into_process(".env");
if (error)
{
vix::print("failed to load .env:", error.message());
return 1;
}vix::error::Error load_layered_into_process(
const EnvFileOptions &options = {});Loads selected dotenv layers and injects their parsed entries into the current process environment.
vix::env::EnvFileOptions options;
options.mode = vix::env::EnvFileMode::Layered;
options.environment_name = "production";
options.load_base_file = true;
options.load_local_file = true;
options.load_environment_file = true;
options.load_environment_local_file = true;
options.ignore_missing_files = true;
options.env.overwrite_existing = true;
auto error = vix::env::load_layered_into_process(options);
if (error)
{
vix::print("failed to load layered environment:", error.message());
return 1;
}After successful injection, values can be read with the normal process environment readers.
auto port = vix::env::get_int("PORT");Environment keys accepted by the module must start with a letter or _. The remaining characters must be letters, digits, or _.
APP_ENV
DATABASE_URL
VIX_LOG_LEVEL
_WORKER_COUNTInvalid keys include:
APP-ENV
1PORT
EMPTY KEYStrict key validation keeps behavior predictable across platforms and avoids accepting names that are unsuitable for normal environment configuration.
#include <vix/env.hpp>
#include <vix/print.hpp>
int main()
{
vix::env::EnvFileOptions options;
options.mode = vix::env::EnvFileMode::Layered;
options.base_dir = ".";
options.filename = ".env";
options.environment_name = "production";
options.load_base_file = true;
options.load_local_file = true;
options.load_environment_file = true;
options.load_environment_local_file = true;
options.ignore_missing_files = true;
options.env.overwrite_existing = false;
auto load_error = vix::env::load_layered_into_process(options);
if (load_error)
{
vix::print("environment load failed:", load_error.message());
return 1;
}
auto app_env = vix::env::get("APP_ENV");
auto port = vix::env::get_int("PORT");
auto debug = vix::env::get_bool("DEBUG");
if (!app_env.ok())
{
vix::print("APP_ENV is required:", app_env.error().message());
return 1;
}
if (!port.ok())
{
vix::print("PORT is required and must be an integer:", port.error().message());
return 1;
}
if (!debug.ok())
{
vix::print("DEBUG is required and must be a boolean:", debug.error().message());
return 1;
}
vix::print("environment:", app_env.value());
vix::print("port:", port.value());
vix::print("debug:", debug.value());
return 0;
}Return to the overview for the conceptual model, or continue through the topic pages when you need more detail about process environment access, typed values, dotenv parsing, layered loading, process injection, options, and error handling.