A reusable Jekyll theme that automatically converts your GitHub repository's README.md files into a beautiful, GitHub-style documentation site with automatic navigation.
| From this… | …to this |
|---|---|
![]() |
![]() |
| https://github.com/lukehefson/surfing/blob/main/README.md | https://lukehefson.com/surfing/ |
This theme scans your repository for all README.md files and creates a documentation website where:
- Each directory with a README becomes a page
- Navigation sidebar automatically shows your directory structure
- Styling matches GitHub's markdown rendering
- Edit buttons link directly to GitHub's edit interface
- Works with nested directories of any depth
- 🎨 Matches GitHub's markdown styling exactly
- 📁 Automatic navigation tree from README files
- 🔄 Collapsible sidebar with localStorage persistence
- 🍞 Breadcrumb navigation
- ✏️ Direct edit links to GitHub
- 🚀 Automatic deployment via GitHub Actions
- 🌐 Supports custom domains
- 📱 Responsive design
Before you begin, make sure you have:
- A GitHub repository with at least one
README.mdfile - Node.js 18+ installed (for the generator script)
- Ruby 3.2+ and Bundler installed (for Jekyll)
- Basic familiarity with Git and GitHub
You have two options:
Option A: Use the Copy Script (Recommended)
If you have this theme repository locally:
-
First, clone or navigate to your target repository (the one you want to apply the theme to):
git clone https://github.com/your-username/your-repo.git # or if already cloned, just note the path -
Then, from the theme repository, run the copy script:
cd /path/to/github-readme-theme ./copy-to-repo.sh /path/to/your-repoThe script will copy all theme files to your target repository. You don't need to be inside the target repo - just provide its path.
Option B: Manual Copy
Copy these files and directories to your repository:
_config.yml
_layouts/
_includes/
assets/
scripts/
.github/workflows/
Gemfile
package.json
.gitignore (or merge with your existing one)
Navigate to your repository and install dependencies:
cd /path/to/your-repo
npm install
bundle installThis will create:
package-lock.json(for npm)Gemfile.lock(for Ruby gems)
Important:
- Commit these lock files to your repository for consistent builds
- If you're on macOS, you need to add Linux platform support (GitHub Actions runs on Linux):
# Add Linux platform to Gemfile.lock (required for GitHub Actions)
bundle lock --add-platform x86_64-linux
# Commit the lock files
git add package-lock.json Gemfile.lock
git commit -m "Add dependency lock files"Edit _config.yml and update these values:
# Repository information for edit links
repo_owner: "your-github-username"
repo_name: "your-repo-name"
repo_branch: "main" # or "master" if that's your default branch
# GitHub Pages configuration
# For project pages (your-repo.github.io/repo-name):
baseurl: "/your-repo-name"
url: "https://your-username.github.io"
# For custom domain (yourdomain.com):
# baseurl: ""
# url: "https://yourdomain.com"Configuration Options Explained:
repo_owner: Your GitHub username or organization namerepo_name: The name of your repositoryrepo_branch: The branch where your README files live (usuallymainormaster)baseurl:- For project pages: Set to
"/your-repo-name"(the repository name) - For custom domains: Set to
""(empty string)
- For project pages: Set to
url:- For project pages:
"https://your-username.github.io" - For custom domains: Your custom domain URL
- For project pages:
Generate the site and test it locally:
npm run generate
npm run serveThis will:
- Scan your repository for all
README.mdfiles - Generate Jekyll pages from them
- Start a local server at
http://localhost:4000
You should see your README files rendered as a documentation site with navigation.
- Go to your repository on GitHub
- Click Settings → Pages (in the left sidebar)
- Under Source, select GitHub Actions (not "Deploy from a branch")
- Save
Commit and push all the theme files:
git add .
git commit -m "Add GitHub README Theme"
git push origin mainThe GitHub Actions workflow will automatically:
- Run the generator script to find all README files
- Build the Jekyll site
- Deploy to GitHub Pages
After deployment completes (usually 1-2 minutes):
- Project pages:
https://your-username.github.io/your-repo-name/ - Custom domain: Your configured domain
You can check the deployment status in the Actions tab of your repository.
Updating the Theme
When the theme repository gets new features or bug fixes, you'll want to update your repository with the latest changes. Here's how:
The _config.yml in any repo that uses the theme contains settings that will be overwritten by the next step — so back that up first:
cd ~/Projects/your-repo-name
cp _config.yml _config.yml.backupFrom the github-readme-theme repository, run the copy script to pull in upstream changes:
cd /path/to/github-readme-theme
./copy-to-repo.sh /path/to/your-repo-nameThis updates:
_layouts/,_includes/,assets/(CSS/JS)scripts/(generator script).github/workflows/(GitHub Actions)Gemfile,package.json,.gitignore
Restore your repo-specific settings that got overwritten in Step 2:
cd ~/Projects/your-repo-name
cp _config.yml.backup _config.yml
# Verify/edit _config.yml has your repo-specific values:
# - repo_owner: "your-username"
# - repo_name: "your-repo-name"
# - baseurl: "/your-repo-name" (or "" for custom domain)
# - url: "https://your-domain.com"npm run generate
npm run servegit add .
git commit -m "Update theme with latest changes"
git pull --no-rebase # Merge any remote changes
git pushNote: If you get merge conflicts:
- For
.github/workflows/build.yml: Use the version from the theme repo (it has deployment enabled) - For generated files (
index.md,_data/nav.json): Regenerate withnpm run generate
The scripts/generate-readme-site.mjs script:
- Scans your repository for all
README.mdfiles (excludingnode_modules,vendor,_generated, etc.) - Generates Jekyll pages in
_generated/and at the root:- Each README becomes an
index.mdfile in its directory - Adds Jekyll front matter with metadata (breadcrumbs, edit URLs, etc.)
- Each README becomes an
- Creates navigation data in
_data/nav.json:- Only includes directories that contain README files
- Builds a hierarchical tree structure
/→ RootREADME.md/<directory>/→<directory>/README.md/<directory>/<subdirectory>/→<directory>/<subdirectory>/README.md
Directory names with spaces are automatically URL-encoded.
- Only directories with READMEs appear in the navigation sidebar
- Navigation tree is built recursively
- Items are sorted alphabetically
- Clicking a directory expands it (if it has children) or navigates to its README
If you want to use a custom domain (e.g., docs.yourdomain.com):
-
Update
_config.yml:baseurl: "" url: "https://docs.yourdomain.com"
-
Configure DNS:
- Add a CNAME record pointing to
your-username.github.io - Or add A records for GitHub Pages IPs (see GitHub's documentation)
- Add a CNAME record pointing to
-
Configure in GitHub:
- Go to Settings → Pages
- Enter your custom domain
- Enable "Enforce HTTPS" (recommended)
-
Commit and push the
_config.ymlchanges
your-repo/
├── _config.yml # Jekyll configuration (edit this!)
├── _layouts/
│ └── default.html # Main layout template
├── _includes/
│ ├── sidebar.html # Navigation sidebar
│ ├── nav_item.html # Recursive nav item
│ ├── breadcrumb.html # Breadcrumb navigation
│ └── edit_button.html # Edit on GitHub button
├── assets/
│ ├── css/
│ │ └── site.css # Custom styles
│ └── js/
│ └── site.js # Sidebar toggle logic
├── scripts/
│ └── generate-readme-site.mjs # Generator script
├── .github/workflows/
│ └── build.yml # GitHub Actions workflow
├── Gemfile # Ruby dependencies
├── package.json # Node.js dependencies
└── README.md # Your root README (this file)
Note: The following are generated automatically and should be in .gitignore:
_generated/- Generated Jekyll pages_data/nav.json- Navigation tree dataindex.mdfiles in directories with READMEs_site/- Built site (for local testing)
# Generate site files from READMEs
npm run generate
# Build Jekyll site (generates _site/)
npm run build
# Generate and serve locally
npm run serveProblem: Site loads but styling is broken.
Solution: Check your baseurl in _config.yml:
- For project pages: Must match your repo name (e.g.,
"/my-repo") - For custom domains: Should be empty (
"")
After fixing, commit and push. You may need to do a hard refresh (Ctrl+Shift+R or Cmd+Shift+R) to clear browser cache.
Problem: Navigation includes directories like vendor/ or node_modules/.
Solution: These should be automatically excluded. If you see them:
- Check that
vendor/andnode_modules/are in your.gitignore - Verify the generator script is up to date
- Check the GitHub Actions logs to see what READMEs are being found
Problem: GitHub Actions workflow fails.
Common causes:
- Missing
package-lock.jsonorGemfile.lock- Commit these files - Ruby version mismatch - The workflow uses Ruby 3.2
- Node version mismatch - The workflow uses Node 20
Check the Actions tab for specific error messages.
Problem: Edit button goes to wrong URL or 404s.
Solution: Verify repo_owner, repo_name, and repo_branch in _config.yml match your repository exactly.
MIT
Contributions welcome! Please feel free to submit issues or pull requests.

