A standalone/GitHub CLI extension to preview GitHub Flavored Markdown, even offline.
Go
128
512 commits
updated Jul 24, 2026
A Go program to preview GitHub Flavored Markdown (GFM) :notebook:.
The gh-gfm-preview command starts a local web server that serves the Markdown
document. gh gfm-preview renders HTML using
yuin/goldmark, extensions, and frontend
tricks to provide features and an appearance similar to GitHub's Markdown
rendering.
It may also be used as a GitHub CLI extension.
This is a hard fork of yusukebe/gh-markdown-preview, which uses the GitHub Markdown API and therefore does not work offline. This repository aims to emulate GitHub's Markdown rendering as closely as possible, but the original project produces a closer match when offline rendering is not required.
Open your browser:

Live reloading:
https://github.com/user-attachments/assets/0219ac01-71d3-4568-bff4-c9de092ca4e3
gh as an extension).| Feature | Supported | Available Offline | Needs JavaScript | Notes |
|---|---|---|---|---|
| GitHub Flavored Markdown specification | Yes | Yes | No | Most of the specification should be supported, thanks to yuin/goldmark and its extensions. |
| Emojis | Yes | Yes | No | Not all GitHub emojis are supported because some are extensions to the Unicode specification, but most work. |
| Alerts | Yes | Yes | No | Custom alert labels such as [!UNKNOWN] are supported but render differently from GitHub. |
| Code blocks with syntax highlighting | Yes | Yes | No | Highlighting uses alecthomas/chroma. Not all GitHub languages are supported, and there are slight differences in highlighting. |
| Section links | Yes | Yes | No | |
| Raw HTML | Yes | Yes | No | No filtering is performed, so arbitrary HTML is allowed. GitHub allows only a subset of HTML. |
| MathJax | Yes | Yes | Yes | |
| Mermaid diagrams | Yes | Yes | Yes | |
| GeoJSON/TopoJSON diagrams | Yes | No | Yes | Rendered with Leaflet and online map tiles. The basemap is OSM-style rather than GitHub’s Azure/TomTom tiles, so it is structurally similar rather than pixel-identical. |
| STL 3D diagrams | No | N/A | N/A | |
| Mentioning people, referencing issues and pull requests, and other features that depend on GitHub access | No | N/A | N/A | Out of scope because they require GitHub API access. |
You need to have gh installed.
gh extension install thiagokokada/gh-gfm-preview
Upgrade:
gh extension upgrade gfm-preview
You need to have Go installed.
go install github.com/thiagokokada/gh-gfm-preview@latest
Assuming that you have Nix flakes enabled:
nix run github:thiagokokada/gh-gfm-preview
To preview a file:
gh gfm-preview README.md
To automatically detect a README file in the current directory:
gh gfm-preview
You can also preview Markdown from standard input by piping data or using -:
echo "# Hello" | gh gfm-preview
cat README.md | gh gfm-preview
gh gfm-preview - < README.md
Then open the local web server, for example at http://localhost:3333, in
your default browser.
Available options:
-p, --port int TCP port number of this server (default 3333)
-H, --host string hostname this server will bind (default "localhost")
-R, --disable-reload disable live reloading
-A, --disable-auto-open disable auto opening your browser
-l, --light-mode force light mode
-d, --dark-mode force dark mode
-m, --markdown-mode force "markdown" mode (rather than default "gfm")
-D, --directory-listing enable directory browsing mode
--directory-listing-show-extensions string file extensions to show in directory listing (comma-separated, use '*' for all files) (default ".md,.txt")
--directory-listing-text-extensions string text file extensions for preview (comma-separated, others will be served as binary) (default ".md,.txt")
--no-color disable color for logs
-v, --verbose show verbose output
--version show program version
Enable directory browsing mode to navigate and preview files:
# Enable with default settings
gh gfm-preview --directory-listing
# Or
gh gfm-preview -D
# Show all file types
gh gfm-preview --directory-listing --directory-listing-show-extensions="*"
# Custom file extensions
gh gfm-preview --directory-listing \
--directory-listing-show-extensions=".md,.rst,.adoc" \
--directory-listing-text-extensions=".md,.txt,.rst"
Because the binary is static and works offline, it is well suited to previewing
how Markdown will look in applications such as
Neovim. For example, you can add this
in your $HOME/.config/nvim/init.lua:
local function preview_markdown()
local file = vim.fn.expand("%")
local on_exit_cb = function(out)
print("Markdown preview process exited with code:", out.code)
end
local process = vim.system(
-- assuming that the extension was installed using gh
-- the reason we are not using `gh gfm-preview` is that this can cause an
-- issue where the gh process is killed but gh-gfm-preview is not, since
-- the kill signal does not reach the child process
{vim.fn.expand("$HOME/.local/share/gh/extensions/gh-gfm-preview/gh-gfm-preview"), file},
on_exit_cb
)
vim.api.nvim_create_autocmd({ "BufUnload", "BufDelete" }, {
buffer = vim.api.nvim_get_current_buf(),
callback = function()
process:kill("sigterm")
-- timeout (in ms), will call SIGKILL upon timeout
process:wait(500)
end,
})
end
-- create a shortcut only in Markdown files, mapped to `<Leader>P`
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = { "markdown" },
callback = function()
vim.keymap.set("n", "<Leader>P", preview_markdown, {
desc = "Markdown preview", buffer = true
})
end,
})
You can run the following command to (re-)generate assets:
go generate ./...
And you can run the following command to build the project:
go build
If you have nix with Flakes enabled:
nix develop
Go
51.3%
CSS
32.0%
JavaScript
8.8%
HTML
6.5%
Nix
1.2%
A standalone/GitHub CLI extension to preview GitHub Flavored Markdown, even offline.
Go
128
512 commits
updated Jul 24, 2026
A Go program to preview GitHub Flavored Markdown (GFM) :notebook:.
The gh-gfm-preview command starts a local web server that serves the Markdown
document. gh gfm-preview renders HTML using
yuin/goldmark, extensions, and frontend
tricks to provide features and an appearance similar to GitHub's Markdown
rendering.
It may also be used as a GitHub CLI extension.
This is a hard fork of yusukebe/gh-markdown-preview, which uses the GitHub Markdown API and therefore does not work offline. This repository aims to emulate GitHub's Markdown rendering as closely as possible, but the original project produces a closer match when offline rendering is not required.
Open your browser:

Live reloading:
https://github.com/user-attachments/assets/0219ac01-71d3-4568-bff4-c9de092ca4e3
gh as an extension).| Feature | Supported | Available Offline | Needs JavaScript | Notes |
|---|---|---|---|---|
| GitHub Flavored Markdown specification | Yes | Yes | No | Most of the specification should be supported, thanks to yuin/goldmark and its extensions. |
| Emojis | Yes | Yes | No | Not all GitHub emojis are supported because some are extensions to the Unicode specification, but most work. |
| Alerts | Yes | Yes | No | Custom alert labels such as [!UNKNOWN] are supported but render differently from GitHub. |
| Code blocks with syntax highlighting | Yes | Yes | No | Highlighting uses alecthomas/chroma. Not all GitHub languages are supported, and there are slight differences in highlighting. |
| Section links | Yes | Yes | No | |
| Raw HTML | Yes | Yes | No | No filtering is performed, so arbitrary HTML is allowed. GitHub allows only a subset of HTML. |
| MathJax | Yes | Yes | Yes | |
| Mermaid diagrams | Yes | Yes | Yes | |
| GeoJSON/TopoJSON diagrams | Yes | No | Yes | Rendered with Leaflet and online map tiles. The basemap is OSM-style rather than GitHub’s Azure/TomTom tiles, so it is structurally similar rather than pixel-identical. |
| STL 3D diagrams | No | N/A | N/A | |
| Mentioning people, referencing issues and pull requests, and other features that depend on GitHub access | No | N/A | N/A | Out of scope because they require GitHub API access. |
You need to have gh installed.
gh extension install thiagokokada/gh-gfm-preview
Upgrade:
gh extension upgrade gfm-preview
You need to have Go installed.
go install github.com/thiagokokada/gh-gfm-preview@latest
Assuming that you have Nix flakes enabled:
nix run github:thiagokokada/gh-gfm-preview
To preview a file:
gh gfm-preview README.md
To automatically detect a README file in the current directory:
gh gfm-preview
You can also preview Markdown from standard input by piping data or using -:
echo "# Hello" | gh gfm-preview
cat README.md | gh gfm-preview
gh gfm-preview - < README.md
Then open the local web server, for example at http://localhost:3333, in
your default browser.
Available options:
-p, --port int TCP port number of this server (default 3333)
-H, --host string hostname this server will bind (default "localhost")
-R, --disable-reload disable live reloading
-A, --disable-auto-open disable auto opening your browser
-l, --light-mode force light mode
-d, --dark-mode force dark mode
-m, --markdown-mode force "markdown" mode (rather than default "gfm")
-D, --directory-listing enable directory browsing mode
--directory-listing-show-extensions string file extensions to show in directory listing (comma-separated, use '*' for all files) (default ".md,.txt")
--directory-listing-text-extensions string text file extensions for preview (comma-separated, others will be served as binary) (default ".md,.txt")
--no-color disable color for logs
-v, --verbose show verbose output
--version show program version
Enable directory browsing mode to navigate and preview files:
# Enable with default settings
gh gfm-preview --directory-listing
# Or
gh gfm-preview -D
# Show all file types
gh gfm-preview --directory-listing --directory-listing-show-extensions="*"
# Custom file extensions
gh gfm-preview --directory-listing \
--directory-listing-show-extensions=".md,.rst,.adoc" \
--directory-listing-text-extensions=".md,.txt,.rst"
Because the binary is static and works offline, it is well suited to previewing
how Markdown will look in applications such as
Neovim. For example, you can add this
in your $HOME/.config/nvim/init.lua:
local function preview_markdown()
local file = vim.fn.expand("%")
local on_exit_cb = function(out)
print("Markdown preview process exited with code:", out.code)
end
local process = vim.system(
-- assuming that the extension was installed using gh
-- the reason we are not using `gh gfm-preview` is that this can cause an
-- issue where the gh process is killed but gh-gfm-preview is not, since
-- the kill signal does not reach the child process
{vim.fn.expand("$HOME/.local/share/gh/extensions/gh-gfm-preview/gh-gfm-preview"), file},
on_exit_cb
)
vim.api.nvim_create_autocmd({ "BufUnload", "BufDelete" }, {
buffer = vim.api.nvim_get_current_buf(),
callback = function()
process:kill("sigterm")
-- timeout (in ms), will call SIGKILL upon timeout
process:wait(500)
end,
})
end
-- create a shortcut only in Markdown files, mapped to `<Leader>P`
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = { "markdown" },
callback = function()
vim.keymap.set("n", "<Leader>P", preview_markdown, {
desc = "Markdown preview", buffer = true
})
end,
})
You can run the following command to (re-)generate assets:
go generate ./...
And you can run the following command to build the project:
go build
If you have nix with Flakes enabled:
nix develop
Go
51.3%
CSS
32.0%
JavaScript
8.8%
HTML
6.5%
Nix
1.2%