Environment Variables
Environment variables come from three sources: the shell environment, .env files and values defined in the build file.
Shell environment
Variables from the shell environment are passed to a command when the task declares them:
tasks:
example:
envs:
VERSION: $VERSION
cmds:
- echo $VERSIONEvery environment variable a task uses should be declared in its envs. Hammerkit checks that each one is defined and otherwise fails with an error, to prevent undesired behavior.
.env file
Environment variables can be defined in a .env file. This is recommended for secret values that should neither be committed nor made public.
NPM_TOKEN=abctasks:
example:
envs:
NPM_TOKEN: $NPM_TOKEN
cmds:
- npm publishDefined values in the build file
Environment variables can be defined in the build file itself. They can be defined for the entire build file or only for specific tasks.
envs:
NODE_VERSION: '22'
tasks:
example:
cmds:
- echo $NODE_VERSION
override_example:
envs:
NODE_VERSION: '20'
cmds:
- echo $NODE_VERSIONVariables defined in a build file are scoped to that file. Neither referenced nor included tasks have access to them.
Precedence
A variable can be defined in more than one place. Hammerkit resolves it like this:
- Task
envswin over build-fileenvson the same key. In the example aboveoverride_exampleprints20, whileexampleprints22. - A value of exactly
$NAMEis a reference that is filled in from, in order:- the shell / process environment, then
- a
.envfile in the build file's directory.
If a referenced $NAME is set nowhere, hammerkit aborts before running with
missing environment variable NAME — references are never silently empty.
Every variable a task uses must be declared in its envs (directly or via
$NAME). Hammerkit only passes declared variables to the command, so an
undeclared shell variable is not leaked into the task.
Interpolation
There are two distinct places a variable can appear:
Inside a command (cmds), $NAME is expanded by the shell at runtime, using
the variables hammerkit passed in — exactly like a normal shell. This is the
echo $NODE_VERSION case above.
Inside other task fields, hammerkit substitutes $NAME itself when it plans
the task — before anything runs. This works for image, src, generates,
mounts, ports, shell, command working directories and a service's image,
so you can drive them from a single value:
envs:
NODE_VERSION: '24'
tasks:
build:
image: node:$NODE_VERSION-alpine # -> node:24-alpine
src:
- src
cmds:
- tsc -bOnly the whole-value $NAME form is recognized in envs (no ${NAME} braces, no
inline prefix-$NAME, no default values). Field substitution matches $NAME
anywhere in the string and is case-insensitive. A value defined directly in envs
(like NODE_VERSION: '24') is what gets substituted into fields such as image.