Environment Variables
Environment variables let you configure your app without hardcoding values. On device, they're stored in NVS and persist across reboots.
Storage is not encrypted
Environment variables are stored as plaintext in NVS flash. Anyone with physical access to the device can dump the flash and read them.
Reading environment variables
The mikro/env module provides explicit methods for reading environment variables:
import {env} from 'mikro/env'
// Required: panics if not set (catches typos and missing config early)
const ssid = env.require('WIFI_SSID')
// Optional: returns undefined if not set
const debug = env.get('DEBUG')
// Check if a variable is set
if (env.has('API_KEY')) {
// ...
}Environment variables are also available on import.meta.env as a standard frozen object. Accessing a missing key returns undefined:
const ssid = import.meta.env.WIFI_SSID // string | undefinedSetting environment variables
With mikro env
The mikro env command reads and writes environment variables directly on the connected device.
Set a secret (prompts for the value, never echoes to your terminal):
npx mikro env set API_KEY
Enter value for API_KEY: ********Set a non-secret (visible in env list, safe to pass on the command line):
npx mikro env set API_URL https://api.example.com --no-secretPassing a VALUE without --no-secret errors. This keeps secrets out of shell history and ps output.
List all variables:
npx mikro env listSecret values are masked in the output; values marked # @no-secret in a .env file remain visible:
WIFI_SSID MyNetwork
API_URL ********
API_KEY ********Delete a variable:
npx mikro env delete API_URLTIP
Variable names can be up to 15 characters (NVS key limit). Use short, descriptive names like WIFI_SSID, API_KEY, MQTT_HOST.
With .env files
mikro dev, mikro deploy, mikro test (and their mikro sim … counterparts) automatically load .env files from the project root. Files use standard dotenv format:
# .env
API_URL=https://api.example.com
API_KEY=sk-…
# Mark a value visible in `mikro env list` (e.g. for debugging):
# @no-secret
WIFI_SSID=MyNetworkEvery entry is treated as a secret by default. Add a # @no-secret comment line directly above an entry to mark just that one variable as visible in mikro env list. A blank line breaks the association.
Precedence
Files are loaded in the order below and merged per key: a variable set in a later source overrides the same variable from an earlier one, while keys a later source doesn't mention are left untouched. The last source therefore has the highest priority.
.env(lowest priority).env.<mode>: where<mode>matches theMIKRO_ENVvalue the command sets (see Built-in variables below). For example:.env.developmentformikro dev,.env.productionformikro deploy,.env.testformikro test,.env.simulatorfor anymikro sim …command.--env-file FILE: an extra file passed explicitly, layered on top (highest priority)
Auto-discovered files (1 and 2) are silently skipped if missing. An explicit --env-file errors if the file doesn't exist. --no-auto-env removes steps 1 and 2, leaving only --env-file if given.
Never commit .env files
The create-mikro scaffold gitignores .env*. Commit .env.example instead to share the shape of the variables your project expects.
Variable name limit
Names must be 15 characters or fewer. The CLI errors with the full list of offending names before deploy if any are too long. This is the NVS key limit on device.
Opting out
Pass --no-auto-env to skip auto-discovery. A file passed via --env-file still loads:
# Skip auto-discovery entirely (deploy with no project env vars)
npx mikro deploy --no-auto-env
# Skip auto-discovery, but still load this one file (e.g. in CI)
npx mikro deploy --no-auto-env --env-file=ci.envBuilt-in variables
MIKRO_ENV
The CLI automatically sets MIKRO_ENV based on the command being run:
| Command | MIKRO_ENV |
|---|---|
mikro dev | development |
mikro deploy | production |
mikro test | test |
mikro sim dev | simulator |
mikro sim deploy | simulator |
mikro sim test | simulator |
You can use this to change behavior based on the current environment:
import {env} from 'mikro/env'
if (env.get('MIKRO_ENV') === 'development') {
// verbose logging, etc.
}If you explicitly set MIKRO_ENV in your .env file, your value takes precedence over the default.
Secrets vs. regular variables
The secret flag describes the intent of a value. It controls whether the value is shown in mikro env list. It does not change how or where the value is stored. All environment variables, secret or not, live in the same plaintext NVS storage and are equally available at runtime via mikro/env and import.meta.env. See Setting environment variables above for how to mark values as secret or non-secret.
Simulator
mikro sim dev, mikro sim deploy, and mikro sim test auto-load .env and .env.simulator from the project root, with the same precedence rules as the device commands. Sim env vars persist in .mikro/nvs.json and can be inspected or edited with mikro sim env list|get|set|delete.