You ask Antigravity's agent to install dependencies, and it fails with a cryptic engine error. Or everything worked yesterday, but today the same npm install is throwing warnings you've never seen before. Nine times out of ten, the culprit is a Node.js version mismatch between what the project expects and what your environment is actually running.
This is especially common in AI-assisted development: when Antigravity sets up a new project or installs packages on your behalf, it executes commands in your terminal environment — and if that environment has the wrong Node version, the errors surface there rather than in a more obvious place. This guide walks through diagnosing the problem and building a setup that keeps it from happening again.
Recognizing the Error Pattern
Three distinct patterns cover most Node.js version mismatch failures.
Pattern 1: npm engines field rejection
npm warn EBADENGINE Unsupported engine {
package: 'some-package@3.0.0',
required: { node: '>=20.0.0' },
current: { node: 'v18.17.0', npm: '9.6.7' }
}
This is the most readable case — the package explicitly declares its Node requirements. npm warn may still complete the install; npm error EBADENGINE stops it entirely.
Pattern 2: Native module build failure
gyp ERR! configure error
gyp ERR! stack Error: Node.js v18.17.0 is not supported
Packages that compile native code (like sharp, sqlite3, or canvas) fail here when the Node version is below their threshold. These errors look more alarming than they are — the fix is still just switching to the right Node version.
Pattern 3: ESM compatibility error
SyntaxError: Cannot use import statement in a module
Modern packages using ES Modules won't run on Node 12 or below. If you see this error, it usually means you're on a very old Node installation. Upgrading to Node 18 LTS or 20 LTS will resolve it in most cases.
Pattern 4: Peer dependency conflict cascades
Sometimes a Node version mismatch doesn't surface directly — it triggers a cascade of peer dependency warnings that end up blocking the install entirely:
npm error ERESOLVE unable to resolve dependency tree
Before assuming this is a genuine dependency conflict, verify your Node version first. Many "unresolvable" dependency trees resolve cleanly once you're on the correct Node version.
Check Your Running Version First
Before making any changes, confirm what Node version Antigravity's terminal is actually using:
# Current Node.js version
node -v
# npm version
npm -v
# Check if nvm is available
nvm --version 2>/dev/null || echo "nvm not installed"
# List installed Node versions
nvm list 2>/dev/nullAntigravity's integrated terminal inherits your shell configuration (.zshrc, .bashrc), so it may be running a different Node version than you expect — especially if you recently installed Node via a package manager like Homebrew, which doesn't always update the PATH entries that nvm relies on. If the version shown doesn't match what your project needs, the sections below cover the fix.
Pin the Version with .nvmrc
The simplest way to specify a Node version per project is a .nvmrc file in the project root:
# Pin to Node 20 (accepts major version or exact version)
echo "20" > .nvmrc
# Or pin to an exact version
echo "20.12.0" > .nvmrcWith .nvmrc in place, switching versions becomes a single command:
# Switch to the version specified in .nvmrc
nvm use
# Expected output:
# Found '/path/to/project/.nvmrc' with version <20>
# Now using node v20.12.0 (npm v10.5.0)When Antigravity's agent runs terminal commands in your project, it recognizes .nvmrc as context about the runtime requirements. Having this file present helps the agent make correct assumptions about which Node version to expect — and it's the first thing another developer (or your future self) will reach for when setting up the project from scratch.
Declare Requirements in package.json
Adding an engines field to package.json communicates the required Node version explicitly:
{
"name": "my-project",
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
}
}By default, npm treats engines mismatches as warnings. To turn them into hard errors — which is generally the right call for any project you care about — add this to .npmrc:
engine-strict=true
With engine-strict enabled, npm install fails immediately on a version mismatch rather than installing silently with a warning. When Antigravity runs installs, this surfaces problems at the right moment — before they turn into mysterious runtime failures hours later.
Installing or Updating nvm
If nvm isn't installed, here's the standard setup:
# Install nvm (check https://github.com/nvm-sh/nvm for the current version)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Reload your shell config
source ~/.zshrc # for zsh
source ~/.bashrc # for bash
# Install Node 20 and set it as default
nvm install 20
nvm use 20
nvm alias default 20The nvm alias default 20 step is the one most people skip — and then wonder why new terminal windows revert to an old Node version. Setting a default ensures that every new shell (including every tab Antigravity opens) starts with the right version.
When nvm use Doesn't Persist
If you find yourself running nvm use every session, you can automate the switch using shell hooks. For zsh, add this to your .zshrc:
# Auto-switch Node version when entering a directory with .nvmrc
autoload -U add-zsh-hook
load-nvmrc() {
local nvmrc_path
nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version
nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
nvm use
fi
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrcWith this in .zshrc, entering a directory that contains .nvmrc automatically switches to the specified Node version. Antigravity's terminal benefits from this too — when the agent navigates between project directories, it ends up using the correct version automatically.
Volta: An Alternative Worth Knowing
nvm works well but has one limitation: version switching happens at the shell level, which means a misconfigured shell hook can leave you on the wrong version. Volta takes a different approach — it pins the Node version at the project level in package.json and enforces it regardless of shell state:
# Install Volta
curl https://get.volta.sh | bash
# Pin Node 20 in your project
volta pin node@20After running volta pin, your package.json gets an entry like this:
{
"volta": {
"node": "20.12.0"
}
}From that point on, every node or npm command in that project directory uses exactly that version — no nvm use, no shell hooks required. If your team struggles to keep Node versions consistent, Volta is worth evaluating.
Dev Container Projects
For projects using Dev Container, specify the Node version directly in .devcontainer/devcontainer.json:
{
"name": "My App",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "20"
}
}
}This locks the version at the container level, making it independent of anything installed on the host machine. Every developer, every CI run, and every Antigravity session inside the Dev Container uses exactly the same Node version — no .nvmrc, no Volta, no version drift.
Notes on pnpm and Bun
pnpm: Checks the engines field by default. For stricter enforcement, add a Node version pin to .npmrc:
node-version=20.0.0
For pnpm monorepos, you can also add engines enforcement to pnpm-workspace.yaml using the onlyBuiltDependencies setting.
Bun: Bun is a separate runtime from Node.js, but packages that compile native modules still call into Node's native APIs internally. Even in a Bun-only project, an outdated system Node can cause build failures. Always check both bun --version and node -v.
Node Version in CI/CD Pipelines
Version mismatches don't only happen locally. If your CI runs npm install on a different Node version than your local environment, you'll see builds pass locally but fail in CI — or the reverse.
For GitHub Actions, pin the Node version explicitly in your workflow file:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc' # reads from .nvmrc automatically
cache: 'npm'
- run: npm ciUsing node-version-file: '.nvmrc' is better than hardcoding a version number directly in the workflow — your .nvmrc becomes the single source of truth for Node version requirements across local development, Antigravity sessions, and CI pipelines.
Verifying the Fix
Once you've updated the Node version, do a clean install to confirm everything resolves correctly:
# Confirm the active version matches what your project expects
node -v
# Clean install — removes cached state that may be masking the real situation
rm -rf node_modules package-lock.json
npm install
# Confirm the install completed without EBADENGINE errors
echo "Install successful"If you ask Antigravity's agent to run a clean install after setting up .nvmrc and the engines field, it will work from the correct version context from the start. That's the state you want: the project's requirements are declared explicitly, and every tool — human, agent, and CI alike — picks them up automatically.
Adding .nvmrc to your project root is the single highest-value thing you can do right now. Everything else in this guide builds on that foundation.