How to Build Cypress from Source: A Complete Guide for Contributors and Custom Builds
Building Cypress from source requires installing dependencies with Yarn 1, compiling the CLI package with Lerna, and building the Electron binary with yarn binary-build while ensuring ELECTRON_RUN_AS_NODE is unset.
Cypress is a complex monorepo that ships two distinct artifacts: the CLI npm package (cypress) and the Electron binary containing the test runner UI. Whether you're contributing to the project, debugging native code, or creating custom builds, understanding how to build Cypress from source is essential. This guide walks through the exact steps implemented in the cypress-io/cypress repository.
Prerequisites for Building Cypress
Before compiling, ensure your environment matches the repository's requirements.
Node Version and Package Manager
Cypress uses a specific Node version declared in .node-version (currently Node 22.x). Native modules like better-sqlite3 are compiled against this exact version.
source .node-version && nvm use
npm install -g yarn@1.22.22
The build scripts in scripts/ensure-node.sh enforce this version check automatically.
System Dependencies
| Platform | Required Packages |
|---|---|
| Linux | build-essential, Xvfb, glibc development headers |
| macOS | Xcode Command Line Tools, Apple code-signing certificate (for distribution) |
| Windows | Visual Studio Build Tools, Git Bash |
Step 1: Clone and Install Dependencies
Pull the repository and run Yarn to install all workspace dependencies and execute post-install hooks:
git clone https://github.com/cypress-io/cypress.git
cd cypress
yarn
This triggers patch-package, V8-snapshot generation, and other preparation steps defined in the root package.json.
Step 2: Build the CLI Package
The CLI package in cli/ must be transpiled from TypeScript to ES5 before it can be published or tested:
yarn lerna run build-cli
Output lands in cli/build/, producing the npm-installable cypress package. The command is declared in the root package.json and executed across Lerna workspaces.
Step 3: Build the Electron Binary
The binary build orchestrates the full monorepo pipeline, including the Electron app, ffmpeg integration, and production dependency bundling.
Critical Environment Variable
Never set ELECTRON_RUN_AS_NODE when building the binary. This variable tells Electron to behave like Node.js, which breaks the build pipeline. Explicitly unset it:
env -u ELECTRON_RUN_AS_NODE \
yarn binary-build --version $(node packages/server/index.js --version) --platform darwin
Available platforms: darwin, linux, win32
macOS Code-Signing
For local testing without a paid Apple Developer account, skip notarization:
SKIP_NOTARIZATION=1 env -u ELECTRON_RUN_AS_NODE yarn binary-build \
--version 13.0.0 \
--platform darwin
Production builds require a valid certificate as documented in guides/code-signing.md.
Step 4: Package the Binary
After building, create the distributable zip that the CLI downloads during cypress install:
yarn binary-package
This produces cypress.zip in the build directory. For CI-ready artifacts matching official releases:
yarn binary-zip
Complete Build Workflow
# Ensure correct Node version
source .node-version && nvm use
# Install global Yarn 1
npm install -g yarn@1
# Clone and enter repository
git clone https://github.com/cypress-io/cypress.git
cd cypress
# Install all workspace dependencies
yarn
# Build CLI transpilation
yarn lerna run build-cli
# Build Electron binary (adjust platform)
env -u ELECTRON_RUN_AS_NODE \
yarn binary-build \
--version $(node packages/server/index.js --version) \
--platform linux
# Package for distribution
yarn binary-package
# Optional: create release-ready zip
yarn binary-zip
Where Build Scripts Live in the Repository
| Step | File Path | Purpose |
|---|---|---|
| Node version enforcement | scripts/ensure-node.sh |
Validates Node matches .node-version |
| CLI build command | package.json (build-cli script) |
Dispatches yarn lerna run build-cli |
| Binary orchestration | scripts/binary.js |
Handles binary-build, binary-package, binary-zip |
| Binary implementation | scripts/binary/index.js |
Electron build, V8-snapshot generation, app packaging |
| Release documentation | guides/building-release-artifacts.md |
Full CLI + binary build reference |
| macOS signing details | guides/code-signing.md |
Certificate and notarization requirements |
Linux Docker Builds for CI Parity
The reference CI environment runs Linux builds. For exact parity with official releases, use the repository's Docker image:
yarn docker
This mounts the source directory into a container with all native build dependencies pre-installed.
Troubleshooting Common Issues
| Symptom | Cause | Solution |
|---|---|---|
Module did not self-register |
Node version mismatch | Run source .node-version && nvm use and re-run yarn |
| Electron build fails silently | ELECTRON_RUN_AS_NODE set |
Prefix command with env -u ELECTRON_RUN_AS_NODE |
| macOS binary won't launch | Missing code signature | Use SKIP_NOTARIZATION=1 for local builds, or provide certificate |
| Yarn workspace errors | Wrong Yarn version | Ensure yarn@1.22.22 is installed globally |
Summary
- Prerequisites: Node 22.x per
.node-version, Yarn 1, and platform-specific build tools - CLI build:
yarn lerna run build-clitranspilescli/tocli/build/ - Binary build:
env -u ELECTRON_RUN_AS_NODE yarn binary-build --version <semver> --platform <name>creates the Electron app - Packaging:
yarn binary-packageproducescypress.zip;yarn binary-zipcreates release artifacts - Source files: Build logic lives in
scripts/binary.js,scripts/binary/index.js, andscripts/ensure-node.sh - Documentation: Full details in
guides/building-release-artifacts.mdandguides/code-signing.md
Frequently Asked Questions
How long does it take to build Cypress from source?
A full source build typically takes 10–30 minutes depending on hardware, with the Electron binary compilation consuming the majority of time. Native module compilation and V8-snapshot generation are the most CPU-intensive steps.
Can I build Cypress from source on Windows?
Yes. Use Git Bash or WSL2 with the Visual Studio Build Tools installed. Pass --platform win32 to the binary build command. The cypress-io/cypress CI runs Windows builds, so the scripts are maintained for this platform.
Why is ELECTRON_RUN_AS_NODE problematic for building?
When ELECTRON_RUN_AS_NODE is set, Electron's executable runs as a Node.js process instead of a full Electron environment. The build pipeline in scripts/binary/index.js expects genuine Electron APIs to be available during the packaging phase, so this variable causes silent failures or malformed binaries.
Do I need an Apple Developer account to build on macOS?
Only for distribution. For local testing and development, set SKIP_NOTARIZATION=1 when running yarn binary-build. This creates an ad-hoc signed binary that functions on your machine but won't pass Gatekeeper on other Macs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →