Matrix Builds
A matrix runs the same job across many versions or platforms in parallel.
A matrix runs one job many times with different inputs — perfect for testing across several language versions or operating systems at once.
How it works
Define strategy.matrix with lists of values. Actions creates one job per combination and runs them in parallel. Reference a value with ${{ matrix.name }}.
Example
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm testWhen to use it
- A library maintainer uses a matrix to test against Node.js 18, 20, and 22 on every push, catching version-specific breakage automatically.
- A cross-platform CLI tool uses a matrix of ubuntu, windows, and macos runners to ensure binaries build correctly on all three.
- A team uses matrix exclusions to skip a known-incompatible combination of OS and runtime, preventing false CI failures.
More examples
Test across Node.js versions
Spawns three parallel jobs — one per Node version — each installing and testing the package in isolation.
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci && npm testMulti-dimension OS and version matrix
Creates a 2x2 matrix with an exclusion that removes the macOS + Python 3.11 combination, resulting in three parallel runs instead of four.
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python: ['3.11', '3.12']
exclude:
- os: macos-latest
python: '3.11'Add extra properties per matrix entry
The include list lets you attach arbitrary extra properties to each matrix combination, useful for labels, flags, or environment variables.
strategy:
matrix:
include:
- os: ubuntu-latest
node: 20
label: LTS
- os: ubuntu-latest
node: 22
label: Current
steps:
- run: echo "Testing Node ${{ matrix.node }} (${{ matrix.label }})"
Discussion