React GitHub Actions: Your First CI/CD Workflow
GitHub Actions is a free CI/CD platform built into every GitHub repository. A workflow is a YAML file that defines automated jobs triggered by events like pushes, pull requests, or scheduled times. In just 5 minutes, you can create your first React workflow to automatically install dependencies, lint, test, and build your app on every code change.
What Is a GitHub Actions Workflow?
A workflow is a configuration file stored in .github/workflows/ that describes a series of jobs. Each job runs in a clean virtual environment (called a runner), executes shell commands and actions, and reports pass/fail status back to your repository. For React apps, workflows enable you to catch bugs before code reaches main, enforce style standards, and verify builds succeed—without any manual intervention.
Workflows are event-driven. Common triggers include:
- push: Runs on every commit to any branch
- pull_request: Runs on PR creation and updates
- schedule: Runs on a cron schedule (e.g., daily)
- workflow_dispatch: Manual trigger from the GitHub UI
Creating Your First Workflow File
Create the file .github/workflows/ci.yml in your React repository root:
name: React CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build React app
run: npm run build
This workflow does the following:
- Checkout (
actions/checkout@v4): Pulls your repository code into the runner - Set up Node.js (
actions/setup-node@v4): Installs Node.js version 20; uses the action-provided Node binary for consistency - Install dependencies (
npm ci): Runsnpm ci(clean install), which respects your package-lock.json exactly and is faster and more deterministic thannpm install - Build (
npm run build): Runs your build script; fails the workflow if the exit code is non-zero
Understanding Runners and Environments
A runner is a real or virtual machine that executes your workflow. GitHub provides free runners:
- ubuntu-latest: Linux environment, most common for Node.js/React
- windows-latest: Windows environment
- macos-latest: macOS environment
Each job runs in isolation on a fresh runner with a clean file system, so you don't have to worry about state from previous runs. All downloaded dependencies, build artifacts, and cached files disappear after the job completes.
Triggering and Viewing Results
Once you push .github/workflows/ci.yml to your repository, GitHub automatically runs the workflow:
- Go to your repository on github.com
- Click the Actions tab
- You'll see workflow runs listed by name and trigger time
- Click a run to view details: which jobs executed, how long each took, and any error messages
If a workflow fails (e.g., the build command exits with code 1), the run is marked as failed and you'll see a red X on your commits and pull requests. Passing workflows show a green check.
Best Practice: Use npm ci, Not npm install
In CI, always use npm ci (clean install) instead of npm install:
# Good: Uses package-lock.json, deterministic
- name: Install dependencies
run: npm ci
# Avoid in CI: May update package-lock.json, non-deterministic
- name: Install dependencies
run: npm install
npm ci respects your lock file exactly and fails if dependencies can't be resolved, making CI behavior predictable and your build reproducible.
Configuring Node Version
The node-version input in actions/setup-node pins the Node version. Common choices:
| Version | Support Status | Recommended For |
|---|---|---|
18 | Maintenance LTS | Legacy/older projects |
20 | Active LTS | Most new projects (2024+) |
22 | Current | Cutting-edge features |
Always pin an LTS (Long Term Support) version in CI to avoid surprise incompatibilities when a new Node release drops.
Key Takeaways
- GitHub Actions workflows are stored in
.github/workflows/*.ymland triggered by push, PR, schedule, or manual dispatch - The
actions/checkoutandactions/setup-nodeactions are reusable, maintained by GitHub and streamline common setup tasks - Always use
npm ciin CI environments to ensure deterministic, reproducible builds - Each job runs on a fresh runner with a clean environment, so state doesn't leak between runs
- Workflow results are visible in the GitHub UI under the Actions tab and on pull requests and commits
Frequently Asked Questions
Can I run the same workflow on multiple branches?
Yes, use the on.push.branches and on.pull_request.branches arrays to specify branch patterns. You can also use wildcards: [main, release/*, develop].
How long do workflows typically run?
Most React apps with npm ci, npm run build, and basic linting run in 2-5 minutes on a GitHub runner. Complex test suites can take longer; that's why caching and parallelization (covered in later articles) are important.
What if my build command is named differently?
Modify the npm run build step to match your package.json. For example, if your script is build:prod, use npm run build:prod.
How do I view logs for a failed step?
Click the workflow run in the Actions tab, then click the failed job. Each step expands to show its full output and error messages, making debugging straightforward.