GitHub Pages
GitHub Pages is free static hosting for any repo. Push HTML, CSS, and JS (or let a build step produce them) and GitHub serves them from a .github.io URL — or your own custom domain — with automatic HTTPS. It is how millions of project sites, blogs, portfolios, and documentation pages are hosted, and it costs nothing for personal use.
What you can host
Static websites — plain HTML, or output of any static site generator (Jekyll, Hugo, Astro, Next.js export, Vite, etc.).
Project documentation rendered from Markdown.
Personal portfolios and blogs.
Single-page apps (React/Vue/Svelte build output).
API documentation generated from OpenAPI/Swagger.
What you cannot host: anything that needs a server (PHP, Node, Rails, Python). Pages is static-only.
URL patterns
Repo name | Type | URL |
|---|---|---|
jsmith.github.io | User/org site | https://jsmith.github.io |
jsmith/blog | Project site | https://jsmith.github.io/blog |
acme/docs | Org project site | https://acme.github.io/docs |
jsmith.github.io/anything | Subpath on user site | https://jsmith.github.io/anything |
You get one site per user (username.github.io) and as many project sites as you have repos.
Enabling Pages
Go to the repo on GitHub. Open Settings → Pages.
Under Source, pick a deployment method (see the three options below).
Save. Within a minute or two, your site is live at the URL shown at the top of the Pages settings.
The three deployment options
1. Deploy from a branch
Simplest path. Pick a branch (commonly main or gh-pages) and a folder (root / or /docs). GitHub runs Jekyll on it (or just serves files as-is if _config.yml is absent) and publishes the result.
The classic gh-pages branch flow
# Build your site into ./dist npm run build # Push dist/ to a gh-pages branch npx gh-pages -d dist # Or manually: git checkout --orphan gh-pages git --work-tree dist add --all git --work-tree dist commit -m "Deploy" git push origin HEAD:gh-pages --force git checkout main
2. GitHub Actions (recommended for everything modern)
Build your site in CI and publish the output. Works with any static generator. Settings → Pages → Source → GitHub Actions.
.github/workflows/pages.yml
name: Deploy site
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: 20 }
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with: { path: ./dist }
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v43. Custom (advanced)
Configure your own workflow that uploads to the Pages artifact endpoint. Same as option 2, just hand-rolled.
Jekyll — the historical default
Drop Markdown files and a _config.yml into your repo, push, and Jekyll builds it into HTML automatically. No build config needed. This is why many older project sites are Jekyll — it was the path of least resistance for years.
A minimal _config.yml
title: My Project description: A few words about it theme: jekyll-theme-cayman markdown: kramdown
Test Jekyll locally before pushing
gem install bundler jekyll bundle init echo 'gem "github-pages", group: :jekyll_plugins' >> Gemfile bundle install bundle exec jekyll serve # http://localhost:4000
Custom domains and HTTPS
Buy a domain wherever you like (Namecheap, Cloudflare Registrar, etc.).
Add a
CNAMEfile at the repo root containing just the bare domain (example.com).At your DNS provider, add an
Arecord for the apex pointing to GitHub Pages IPs (185.199.108.153, 185.199.109.153, 185.199.110.153, 185.199.111.153), or anALIAS/ANAMEif your DNS supports it.For
www.example.com, add aCNAMErecord pointing tojsmith.github.io.Wait a few minutes, then in Settings → Pages, GitHub provisions a Let's Encrypt certificate. Check Enforce HTTPS.
CNAME file at repo root
example.com
Limits
Resource | Limit |
|---|---|
Repo size | 1 GB recommended (10 GB hard cap) |
Site size | 1 GB |
Bandwidth | 100 GB/month soft limit |
Builds | 10 per hour for branch-based deploys |
Custom domains | No HTTPS for unverified domains |
File types served | Static files only — no server-side execution |
These are generous for personal projects. If you blow past 100 GB/month you should be using Netlify, Vercel, or Cloudflare Pages instead.
Pages for any modern stack
Next.js —
next build && next export(oroutput: "export"innext.config.js), then publishout/.Astro —
npm run build, publishdist/.Hugo —
hugo, publishpublic/.Vite —
vite build, publishdist/. Setbase: "/repo-name/"for project sites.MkDocs / Docusaurus / Sphinx — all have first-class GitHub Pages publishers.
The decision tree
Pages vs Netlify vs Vercel
Need server functions / SSR / Edge? -> Vercel / Netlify / Cloudflare Need a custom build process? -> Pages with Actions (free) Just static HTML? -> Pages with branch deploy Documentation for an open-source repo? -> Pages (it's the convention) Production site with > 100 GB traffic? -> Move to a CDN-backed host