
To set up a CI/CD pipeline for a startup in 2026, run GitHub Actions for tests, lint, and typecheck on every PR, then let your host (Vercel, Render, or Cloudflare Workers) auto-deploy on merge to main. Add branch protection with required checks and per-PR preview environments. Skip CircleCI and Buildkite until you cross 30 engineers.
That is the entire playbook. The rest of this post is the literal YAML, the host-by-host setup, and the honest trade-offs so you can ship the whole thing in an afternoon.
A startup pipeline does four jobs. It catches bad code before merge (lint, typecheck, unit tests). It builds a deployable artifact. It pushes that artifact to a preview environment per pull request so your designer or PM can click around. It pushes to production when you merge to main.
Anything beyond those four jobs is enterprise scaffolding you do not need yet. You do not need a multi-stage Argo CD rollout, a service mesh, or a Dockerfile that compiles in three layers. You need a green check on every PR and a working preview URL.
The 2026 default is to run all four jobs on hosted runners (GitHub Actions plus your host's auto-deploy), not on self-hosted infrastructure. Hosted runners trade money for engineering time, and at startup scale that math is not close. GitHub Actions gives you 2,000 free minutes per month on Free, 3,000 on Pro, and 50,000 on Team. Most pre-Series A teams never hit the Pro cap.
Here is the stack you want, in order of importance:
.github/workflows/ next to your code. No second account, no second billing relationship, no separate access control.That is the full stack. No CircleCI, no Buildkite, no Jenkins, no GitLab Runner pool. If you are reading "but what about..." right now, the answer is almost certainly no until you are past 30 engineers.
Honest comparison. CI and CD overlap, so this table mixes both.
| Tool | Best for | Free tier | Setup time | Honest take |
|---|---|---|---|---|
| GitHub Actions | Almost every startup | 2,000 min/mo | 30 min | Default pick. Workflows live next to code. |
| Vercel auto-deploy | Next.js / frontend / full-stack JS | Unlimited preview deploys | 5 min | Best preview-deploy story in the market. |
| Render auto-deploy | Backend services + Postgres + cron | Branch deploys included | 10 min | Quietly the best Heroku replacement. |
| Cloudflare Workers | Edge-first apps, global low-latency | Per-PR preview URLs | 15 min | Cheapest at scale, smaller plugin ecosystem. |
| CircleCI | Multi-repo, multi-language, non-GitHub | 6,000 min/mo | 1-2 hours | Strong if you are not on GitHub. Otherwise duplicative. |
| Buildkite | 30+ engineers, regulated industries | Self-hosted agents | 1+ day | Best at scale. Wrong tool until you get there. |
Where CircleCI wins. If your code lives on Bitbucket or self-hosted GitLab, CircleCI is the cleanest answer because GitHub Actions is GitHub-only. The orb library (3,500+ reusable blocks) is also genuinely better than the GitHub Actions Marketplace for some niche workflows (Salesforce deploys, mobile signing, mainframe tooling).
Where Buildkite wins. Once you are past 30 engineers and your CI bill is real, Buildkite's self-hosted agent model lets you run unlimited concurrent jobs on cheap cloud VMs while keeping the control plane managed. Block & Shopify both run massive Buildkite fleets for this reason. For a 5-engineer startup, this is the wrong problem.
The migration trigger is simple: when your monthly GitHub Actions bill exceeds 50% of one engineer-week, evaluate Buildkite. Until then, the time you would spend evaluating is worth more than the money you would save.
This is the literal walkthrough. Pick GitHub Actions plus Vercel for a Next.js or React app, or GitHub Actions plus Render for a backend service. Substitute as needed.
Create a Vercel or Render account. Connect your GitHub org. Import the repo. Both will auto-detect the framework, prompt you for env vars, and run the first deploy in under 5 minutes. From this moment on, every push to a branch creates a preview URL, and every merge to main updates production. You have technically already shipped CD.
Create .github/workflows/ci.yml:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test -- --run
- run: npm run build
That is the whole CI file. Five steps, runs in 3-5 minutes for most repos, costs roughly 50 free-tier minutes per PR.
For a Python backend on Render, swap to:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: pip
- run: pip install -r requirements.txt
- run: ruff check .
- run: mypy .
- run: pytest -q
Go to Settings → Branches → Add rule for main. Check:
check jobWithout this step, your CI is decorative. Anyone can merge a red PR. Many teams skip this for "speed" and immediately regret it the first time main is broken on a Friday.
Open a throwaway PR. Within 60 seconds you should see two GitHub status checks (your CI workflow plus a Vercel/Render preview deploy comment with a URL). Click the URL. If it loads, your PR-review loop is now: open PR, designer clicks the preview link, reviewer reads diff, merge.
This is the loop that makes the pipeline pay for itself. A founder who can review work from their phone without pulling a branch is worth more than any test-coverage badge.
Merge a real change. Watch it deploy. Production is now downstream of main, full stop. No more "ssh in and pull", no manual deploys, no cron-triggered scripts. If you previously ran a manual deploy script, delete it. The temptation to "just SSH in real quick" is the exact failure mode CD prevents.
Pipelines that ship fast also break fast. Bolt on three things in the first month:
/healthz and /api/healthz.That is the entire afternoon. Tests, lint, typecheck, preview deploys, branch protection, prod deploy, monitoring. Six steps, one YAML file, two dashboards.
Two patterns dominate, and the choice matters more than tool choice.
Deploy-on-merge. Every merge to main deploys to production. Default for almost every startup. Pros: zero ceremony, fastest feedback loop, no "is the deploy lined up with the release notes?" anxiety. Cons: you cannot pause production deploys without stopping merges to main.
Deploy-on-tag. Production deploys only when you push a git tag like v1.4.2. Common at fintech, healthtech, and any startup with a compliance auditor in the loop. Pros: explicit production releases, easy audit trail, can hold prod for marketing launches. Cons: extra step, easier to forget, slower feedback loop.
The hybrid pattern: deploy-on-merge to a staging environment, deploy-on-tag to production. This costs you nothing on Vercel and Render (both support multiple environments natively) and gives you the audit trail without sacrificing iteration speed. We recommend it for any startup with paying customers and one or more enterprise contracts.
Patterns that look correct and break in production.
cache: to every setup-node / setup-python action. Most slow CI is uncached dependency installs.continue-on-error: true until you fix them. Don't tolerate them in the main check.${{ secrets.DATABASE_URL }}. For GDPR-relevant work this matters even more, see GDPR for SaaS apps.npm ci && npm run build works, ship it. Multi-stage Docker builds add 5-10 minutes per pipeline run for zero startup-stage benefit.If you ship on Vercel, the deploy a Next.js app to Vercel like a pro guide covers Vercel-specific gotchas (env-var scoping, ISR cache invalidation, edge function cold-starts) that the generic CI/CD setup does not.
Honest scope. You do not need a pipeline if:
Once you have one paying customer or one collaborator who is not you, set up the pipeline above. The cost is one afternoon. The cost of not having it is one all-nighter the first time you ship a regression to production manually.
Most solo founders do not want to learn YAML on a Tuesday. The CI/CD setup, branch protection, preview deploys, monitoring, and rollback playbook is roughly 4-6 hours of senior engineering work. If you have an in-house engineer, hand them this post and a coffee.
If you do not, this is exactly the kind of bounded engineering project Cadence is built for. Every engineer on Cadence is AI-native by default, vetted on Cursor, Claude Code, and Copilot fluency before they unlock bookings, and our senior tier ($1,500/week) typically owns CI/CD rollouts end-to-end. Median time to first commit across our 12,800-engineer pool is 27 hours, so you can have a green pipeline by Wednesday if you book on Monday.
If you would rather audit your existing setup before booking anyone, run your stack through Ship-or-Skip for an honest grade on what to keep and what to rip out.
.github/workflows/ci.yml with checkout, setup-node (or setup-python), npm ci, lint, typecheck, test, and build jobs.If you would rather skip the YAML and have a senior engineer do this in 4 hours, book a Cadence engineer with a 48-hour free trial. Weekly billing, no notice period, replace any week.
An afternoon for a basic GitHub Actions plus Vercel or Render pipeline. A senior engineer can have tests, lint, typecheck, preview deploys, and branch protection live in roughly 4 hours.
Not until you are past 30 engineers or hitting GitHub's 50,000-minute Team cap. Self-hosting trades cash for engineering time, and that math rarely works for startups under Series B.
No. Most startups can ship for years on native Node or Python builds. Add Docker only when you have multi-service backends with shared base images or specific runtime-parity needs.
When monthly build minutes exceed the Team plan (50,000/mo), when you have 30+ engineers, or when compliance requires self-hosted agents. Until then, migration cost beats the saving.
$0 for the first 6-12 months on GitHub Actions free tier plus a Vercel or Render hobby plan. Expect $50-300/month once you are past 5 engineers and want faster runners or higher concurrency.