Skip to content

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:

ts
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:

ts
const ssid = import.meta.env.WIFI_SSID // string | undefined

Setting 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):

sh
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):

sh
npx mikro env set API_URL https://api.example.com --no-secret

Passing a VALUE without --no-secret errors. This keeps secrets out of shell history and ps output.

List all variables:

sh
npx mikro env list

Secret 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:

sh
npx mikro env delete API_URL

TIP

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:

sh
# .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=MyNetwork

Every 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.

  1. .env (lowest priority)
  2. .env.<mode>: where <mode> matches the MIKRO_ENV value the command sets (see Built-in variables below). For example: .env.development for mikro dev, .env.production for mikro deploy, .env.test for mikro test, .env.simulator for any mikro sim … command.
  3. --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:

sh
# 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.env

Built-in variables ​

MIKRO_ENV ​

The CLI automatically sets MIKRO_ENV based on the command being run:

CommandMIKRO_ENV
mikro devdevelopment
mikro deployproduction
mikro testtest
mikro sim devsimulator
mikro sim deploysimulator
mikro sim testsimulator

You can use this to change behavior based on the current environment:

ts
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.

Mikro.js is built with AI assistance, code and docs alike. Read the AI disclosure.