SkunkHTML
The simplest way to run a blog on GitHub Pages.
Fork this repo (or use it as a template). Enable GitHub Pages. You have a blog. That's it.
No CLI to install. No config files to learn. No build tools on your machine. Write Markdown, push to GitHub, your site updates automatically.
See it in action: Live demo
Get started in 60 seconds
- Fork this repository
- Go to Settings > Pages > Source: GitHub Actions
- Your blog is live at
https://YOUR-USERNAME.github.io/skunk-html/
To publish a post: add a Markdown file to the markdown-blog/ folder. The file name is the date - name it like 2025-03-24.md and start the file with a # Title heading. The title comes from the heading, the date comes from the file name. Push. Done.
Features
- Zero local setup - everything runs on GitHub Actions
- Markdown -> HTML - write in Markdown, get a clean website
- RSS feed - your readers can subscribe (
/feed.xml) - Sitemap - search engines find your content (
/sitemap.xml) - SEO meta tags - Open Graph and Twitter Cards out of the box
- 404 page - a "not found" page in your site's style, generated automatically
- Dark mode - respects your visitors' system preference automatically
- Themes - choose from built-in color themes or tweak CSS variables
- Comments - optional Giscus integration
- Syntax highlighting - code blocks are highlighted automatically
- No dependencies on your machine - no Node.js, no Ruby, no Go
Customize your site
Edit Config.fs - you only need to change the values in quotes:
let siteTitle = "My Blog" let siteDescription = "A blog powered by SkunkHTML" let siteBaseUrl = "https://YOUR-USERNAME.github.io/skunk-html" // No trailing slash let siteLanguage = "en" let siteAuthor = "Your Name" let siteImage = "assets/avatar.jpg" // Preview image for social shares
You don't need to know F# - just edit the text between the quotation marks. The same file also contains the interface texts (like the "blog entries" heading and the 404 page messages) - translate them if your blog is not in English.
Base URL examples - set siteBaseUrl to match where your site is hosted:
- GitHub project page:
https://YOUR-USERNAME.github.io/skunk-html - GitHub user page (repo named
<user>.github.io):https://YOUR-USERNAME.github.io - Custom domain:
https://example.com - Self-hosted with subpath:
https://example.com/blog
Themes
SkunkHTML ships with multiple color themes. To switch themes, copy the contents of a theme file from themes/ into css/tweaks.css:
| Theme | File | Style |
|---|---|---|
| Default | css/tweaks.css |
Clean, minimal with dark mode |
| Ocean | themes/theme-ocean.css |
Cool blue tones (GitHub-inspired) |
| Terminal | themes/theme-terminal.css |
Green-on-dark hacker aesthetic |
| Ink | themes/theme-ink.css |
Warm serif typography (newspaper-inspired) |
All themes respect prefers-color-scheme - they look great in both light and dark mode.
Content structure
- Blog posts: Markdown files in
markdown-blog/whose names start with a digit. The file name is the publication date (e.g.2025-03-24.md). The post title comes from the first# Headinginside the file. - Other pages: Markdown files in
markdown-blog/that don't start with a digit (e.g.about.md,featured.md) - Front page:
markdown-blog/index.md- optional welcome content displayed above the post list
HTML fragments
Customize the header, footer, and page head by editing files in html/:
header.html- site navigation and logofooter.html- footer contenthead.html- meta tags, CSS links, and faviconsscript_giscus.html- Giscus comments configuration
Folder structure
skunk-html/
├── .github/workflows/ # GitHub Actions build & deploy
├── assets/ # Avatar, favicon, shared resources
├── css/ # Stylesheets (styles.css + tweaks.css)
├── fonts/ # Custom fonts
├── html/ # HTML fragments (header, footer, head)
├── markdown-blog/ # Your content goes here
│ └── images/ # Images used in articles
├── scripts/ # Syntax highlighting script
├── themes/ # Alternative color themes
├── Config.fs # Your site settings (title, URL, texts)
├── SkunkUtils.fs # Utility functions
├── SkunkHtml.fs # HTML generation engine
├── Program.fs # Build entry point
└── skunk-html.fsproj # F# project file
Updating
To pick up engine improvements later, use GitHub's Sync fork button (or merge upstream manually). Everything that makes your blog yours lives in Config.fs and the content folders (markdown-blog/, html/, css/, assets/, fonts/) - engine updates normally don't touch those, so syncing merges cleanly.
Optional: build locally
You don't need this for normal use - GitHub Actions handles everything. But if you want to preview locally:
git clone https://github.com/mg0x7BE/skunk-html.git cd skunk-html dotnet restore dotnet run
Your site will be in skunk-html-output/. Requires .NET.
How it works
When you push a Markdown file to markdown-blog/, GitHub Actions runs a small F# program that converts your Markdown to HTML using FSharp.Formatting, generates RSS and sitemap, wraps everything in a clean layout based on MVP.css, and deploys to GitHub Pages.
The entire build engine is ~400 lines of F#. No frameworks. No plugins. No magic.
Contributing
Suggestions, bug reports, and pull requests welcome. Use discussions, issues, or PRs.
License
Unlicense - do whatever you want with it.
Dependencies
- MVP.css - styling
- microlight.js - syntax highlighting
- FSharp.Formatting - Markdown processing
more like this
markItDown
📱 A React app to preview and edit Markdown✍. You can also export it as HTML.