Skip to main content

GitHub Pages — host a repo as a static site

GitHub Pages turns a GitHub repository into a free static website. It serves plain HTML/CSS/JS or the build output of any static site generator (Jekyll, Hugo, Vite, Astro, …).

7 viewsAbout 3 min read
Table of contents

GitHub Pages turns a GitHub repository into a free static website. It serves plain HTML/CSS/JS or the build output of any static site generator (Jekyll, Hugo, Vite, Astro, …).

1. Where it fits

Year Event
2008 Tom Preston-Werner introduced it alongside GitHub (Jekyll-based).
2014+ Free HTTPS for custom domains (later via Let's Encrypt).
2018+ GitHub Actions integration — any SSG works.
2022+ Actions-based deploy is the recommended default.

Core value:

  • Repo = site. Free with generous limits (100GB/month soft, 10 builds/hour).
  • HTTPS · custom domain · CDN included.
  • Static only — no backend, no DB.

2. Two deploy modes

(a) Branch — serve a folder directly

Pick a branch (main or gh-pages) and serve its root or /docs folder. The SSG-built dist/ is committed and pushed. Simple sites only.

Build with any SSG, upload artifact, deploy via Pages. Default since 2022.

# .github/workflows/deploy.yml — Vite example
name: Deploy to GitHub Pages
on:
  push:
    branches: [main]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: github-pages
    steps:
      - uses: actions/deploy-pages@v4

3. URL patterns

Repo type URL
<user>.github.io (User site) https://<user>.github.io/
<org>.github.io (Org site) https://<org>.github.io/
<user>/<repo> (Project site) https://<user>.github.io/<repo>/
Custom domain https://example.com/

Project sites have a /repo path prefix — set Vite's base: '/<repo>/', Next.js basePath, etc. User/org sites have no prefix.

4. Custom domain

CNAME file

Add a CNAME file at repo root (one line, your domain) or set it in the GitHub UI.

DNS

  • apex (example.com) — A records: 185.199.108.153 · .109.153 · .110.153 · .111.153
  • www / subdomain — CNAME → <user>.github.io

Then enable "Enforce HTTPS" in the UI (Let's Encrypt issues automatically).

5. Env / Secrets

Build-time secrets via GitHub Actions Secrets (Settings → Secrets and variables → Actions). Only public values (e.g. NEXT_PUBLIC_*) make sense — anything baked into the static build is visible to clients.

For runtime API keys, you need a backend (Cloudflare Workers, Netlify Functions, Replit, your own host).

6. Limits — what you can't do

  • No server code — no Express/FastAPI/Spring. No SSR (only static export).
  • No DB — all data is baked in at build time or fetched from an external API.
  • Forms — submit via external services (Formspree · Getform · Cloudflare Forms).
  • Bandwidth — soft 100GB/month. Rarely enforced in practice.
  • Build minutes — free Actions limits apply on private repos. Public repos are unlimited.

7. SSG quick-setup

Vite (React/Vue)

export default defineConfig({
  base: '/<repo>/',
  plugins: [react()],
});

Next.js (Static Export)

export default {
  output: 'export',
  basePath: '/<repo>',
  images: { unoptimized: true },
};

Astro

export default defineConfig({
  site: 'https://<user>.github.io',
  base: '/<repo>',
});

Hugo

baseURL = "https://<user>.github.io/<repo>/"

8. vs Replit / Vercel / Netlify

Aspect GitHub Pages Replit Static Vercel Netlify
Cost (free tier) unlimited (soft) 1 deployment free hobby 100GB starter 100GB
Custom domain (free) ✗ (Core needed)
Auto HTTPS
SSR · Edge partial
Build minutes (public) unlimited (Actions) fast fast fast
Preview deployments
Learning curve medium (Actions) very low low low

For OSS docs, portfolios, and blogs, GitHub Pages is free, stable, and integrated. For dynamic features, pick Vercel / Netlify. For an integrated learning IDE, pick Replit.

9. Good fits

  • Open-source project docs (auto-deploy docs/).
  • Personal blog / portfolio (Astro, Hugo, Jekyll).
  • Single-page React/Vue app (Vite + GH Pages).
  • Slide decks / small guides.

10. Poor fits

  • Full-stack app needing SSR / API / DB.
  • Auth · sessions · realtime (you'd need an external backend anyway).
  • Heavy traffic (>100GB).
  • Frequent builds on private repos (Actions minutes).

11. Further reading

More in cloud

All in this category →

Was this article helpful?