GitHub Flow
GitHub Flow is a lightweight, continuous delivery-oriented workflow created by GitHub and used by GitHub itself to deploy hundreds of times per day. It strips Git Flow's complexity down to the essentials: one long-lived branch (main), short-lived feature branches, Pull Requests, and deployment before merging. Its simplicity makes it the most popular workflow for SaaS web applications and teams that practice continuous deployment.
The 6-step cycle
Branch — create a descriptively named branch from
main.Commit — make small, focused commits on the branch.
Pull Request — open a PR as soon as the first commit is pushed (even as a draft).
Review — team members review, comment, and approve the PR.
Deploy — deploy the branch to a staging/production environment to verify it works.
Merge — once verified in production (or staging), merge the PR into
main.
GitHub Flow diagram
GitHub Flow topology
main: A ── B ──────────────── M1 ─────────── M2 ──▶
│ ↑ ↑
│ (merge) (merge)
│ │ │
feature/auth: └── C ── D ── E │
(deployed to ──────┘
staging, verified)
feature/search: └── F ── G ── H ──────┘
(deployed &
verified)
main is ALWAYS deployable.
Features are deployed BEFORE merging into main.Complete command walkthrough
Step 1: Create a branch from main
# Always start from a fresh main git switch main git pull origin main # Create a descriptive branch git switch -c feature/add-user-avatars # Switched to a new branch 'feature/add-user-avatars'
Step 2: Commit your work
# Make small, focused commits git add src/components/Avatar.tsx git commit -m "feat: add Avatar component with size variants" git add src/hooks/useAvatar.ts git commit -m "feat: add useAvatar hook for Gravatar fallback" git add tests/Avatar.test.tsx git commit -m "test: add Avatar rendering tests"
Step 3: Push and open a Pull Request
# Push the branch git push -u origin feature/add-user-avatars # Open a PR (GitHub CLI): gh pr create --title "Add user avatar support" --body "Adds Avatar component with Gravatar fallback. Closes #45." --draft # Start as draft while still working # When ready for review, mark it ready: gh pr ready
Step 4: Review and address feedback
# After review comments arrive, fix them: git add src/components/Avatar.tsx git commit -m "fix: handle missing Gravatar email gracefully" # Push the updated branch — PR updates automatically git push origin feature/add-user-avatars
Step 5: Deploy the branch to staging/production
# GitHub Actions example — deploy branch to staging when PR is opened
# .github/workflows/deploy-preview.yml:
# on: [pull_request]
# jobs:
# deploy:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - run: npm ci && npm run build
# - run: ./deploy.sh staging ${{ github.head_ref }}
# Heroku Review Apps, Vercel Preview, Netlify Preview do this automatically.
# Verify the feature works correctly in the deployed environmentStep 6: Merge after verification
# Merge via GitHub UI (squash, rebase, or merge commit) # or via CLI: gh pr merge feature/add-user-avatars --squash --delete-branch # ✓ Squashed and merged pull request #46 # ✓ Deleted branch 'feature/add-user-avatars' # Pull the updated main locally git switch main git pull origin main
Continuous deployment friendly
GitHub Flow is designed around the idea that main is always deployable. In many teams, merging to main automatically triggers a deployment pipeline. The "deploy before merge" step (step 5) is what makes this safe — you verify the change works in production context before it permanently enters the main branch.
Automated deployment pipeline on merge to main
Developer merges PR to main
│
▼
GitHub Actions / CircleCI / Jenkins triggered
│
├── Run unit tests
├── Run integration tests
├── Build production artifacts
└── Deploy to production
│
▼
Production updated ✓GitHub Flow vs Git Flow
Dimension | GitHub Flow | Git Flow |
|---|---|---|
Long-lived branches | 1 (main) | 2 (main + develop) |
Release branches | No | Yes (release/*) |
Hotfix branches | No (fix via a PR like any other change) | Yes (hotfix/*) |
Feature branches | Yes | Yes |
Deployment trigger | Branch deploy before merge | Merge to main (tagged) |
Release cadence | Continuous (many per day) | Scheduled (per sprint or milestone) |
Versioned releases | Rarely (or via tags on main) | Yes — central to the model |
Complexity | Low | High |
Best for | SaaS, web apps, continuous delivery | Libraries, apps with versioned releases |
Who uses GitHub Flow
GitHub itself — the company that created this workflow uses it to deploy multiple times per day.
Most SaaS web application teams — single production environment, continuous deployment.
Startups and small-to-medium teams — the simplicity reduces coordination overhead.
Open-source projects — many popular projects (including some large ones) use this model.
Teams adopting CI/CD — GitHub Flow works naturally with automated testing and deployment pipelines.
Handling hotfixes in GitHub Flow
GitHub Flow has no dedicated hotfix branch type. An emergency fix is just another branch from main, with the same PR and review process — but with urgency. Because main is always deployable, hotfixes are less stressful: you never need to cherry-pick across multiple branches.
Emergency fix in GitHub Flow
# Same process as any other change — just faster git switch main git pull origin main git switch -c fix/critical-payment-bug git commit -m "fix: prevent null pointer in checkout flow" git push -u origin fix/critical-payment-bug # Open PR, get expedited review, merge gh pr create --title "URGENT: fix payment null pointer" --body "Fixes #99" # (after quick review and CI pass) gh pr merge --squash --delete-branch