gh markdown-preview shows your README the way GitHub will render it
GitHub CLI extension to preview Markdown looks like GitHub.
At a glance
- What is it?
- gh markdown-preview is a GitHub CLI extension that starts a local web server and renders a Markdown file with the HTML that GitHub's own markdown API returns, styled with CSS taken from the GitHub website, with live reloading as you edit. It is a Go binary, it needs nothing but the gh command, and it asks for no access token.
- Who is it for?
- Adopt gh markdown-preview if you write documentation in Markdown and want to know how it will look on GitHub before you push it, and if you are happy for the preview to be rendered by GitHub's API over the network. Do not adopt it as an offline renderer or as a general Markdown to HTML converter, because the fidelity comes from Gitub's own rendering rather than from a local parser.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The fidelity comes from GitHub, not from a local parser
gh markdown-preview is a GitHub CLI extension to preview your Markdown, such as a README file. The command starts a local web server to serve the markdown document, renders the HTML it got from GitHub's official markdown API, and uses the CSS extracted from the GitHub website. The README puts it plainly: the styles are almost the same, and you can see the rendered README before uploading to GitHub.
That is the whole design, and it is a smart one. The usual reason a local preview disagrees with GitHub is that the preview uses a different Markdown parser, a different set of extensions and a different stylesheet. This tool sidesteps that by using GitHub's own renderer for the HTML and GitHub's own CSS for the styling, so the only difference between the preview and the real thing is the surroundings of the page.
The features list makes the practical consequences clear. There are no dependencies beyond the gh command itself, there is zero configuration because you do not have to set a GitHub access token, the browser is opened automatically, an available port is found automatically if the default is taken, and live reloading means you do not have to reload the browser as you edit.
The audience is whoever writes the documentation in a repository, which in practice means most developers who keep a README. The zero dependency claim is the one that makes it easy to recommend to a colleague, because there is nothing to install beyond the GitHub CLI that the reviewer already has, and nothing to configure before it works.
Install it as a gh extension, run it on a file
The installation is the GitHub CLI extension mechanism:
gh extension install yusukebe/gh-markdown-previewUpgrading is the same command with upgrade and the short name:
gh extension upgrade markdown-previewThe usage is a single argument, the file you want to see:
gh markdown-preview README.mdAnd if you leave the argument out, the command detects the README file in the directory automatically, which is the form most people will end up typing:
gh markdown-previewStdin works too, which is useful when the document is generated rather than checked in:
echo "# Hello" | gh markdown-preview
cat README.md | gh markdown-preview
gh markdown-preview - < README.mdThe last of those three is the explicit form, with a dash standing in for the file argument, and the first two pipe the content in. The README then tells you to access the local web server at the localhost address on port 3333 with Chrome, Firefox or Safari.
So the loop is: run the command, your browser opens on the rendered page, you edit the file, and the page updates itself. That last part is the one that turns this from a curiosity into a tool you use while writing, and it is why the feature list bothers with an option to turn it off.
The options are the API surface, and there are only nine
The available options are printed in the README, and they are worth reading in full because they tell you exactly what the tool does and does not do.
--dark-mode Force dark mode
--markdown-mode Force "markdown" mode (rather than default "gfm")
--disable-auto-open Disable auto opening your browser
--disable-reload Disable live reloading
-h, --help help for gh-markdown-preview
--host string Hostname this server will bind (default "localhost")
--light-mode Force light mode
-p, --port int TCP port number of this server (default 3333)
--verbose Show verbose output
--version Show the versionTwo of these are about the rendering rather than the serving. The default rendering mode is gfm, which is GitHub Flavored Markdown, and the markdown-mode flag forces the plain markdown mode instead, which is how you check what a file looks like outside a GitHub context. The dark-mode and light-mode flags force one or the other, and they exist because GitHub's own stylesheet is served as a set of rules for both, so the preview can pin whichever one your editor is in.
The rest are about the local server. The host defaults to localhost and the port to 3333, and the auto open and the live reload can each be disabled. The verbose flag exists for when the server does not come up where you expect it to.
What is missing from this list is as informative as what is on it. There is no option for the CSS file, no option for a template, no option to preview several files at once and no option to run without a network connection. The tool does one thing, and the nine flags are the whole of its configurability.
Live reloading is a file watcher and a websocket
The mechanism behind the live reload is visible in the module dependencies, and it is a conventional and small implementation.
require (
github.com/cli/safeexec v1.0.0
github.com/fsnotify/fsnotify v1.5.1
github.com/gorilla/websocket v1.4.2
github.com/spf13/cobra v1.2.1
)fsnotify is the file watching library, so the tool watches the file you asked it to render and notices when it changes. gorilla/websocket is how the browser is told to refresh, since a plain HTTP server has no way to push anything to a page that is already open. cobra is the command line framework that produces the flag set above, and safeexec comes from the GitHub CLI organisation and is there to run commands without a shell in the way, which matters when a tool is launching something like a browser.
So the reload path is: the file changes, fsnotify fires, the server re-renders the document by asking GitHub's markdown API again, and the websocket connection tells the page to update. That is worth noticing, because it means every keystroke-triggered save causes a new call to the GitHub API. The README does not discuss rate limits or caching, and there is no option to control how often the re-render happens, so on a large document with fast saving you are making a request per save.
The Go version in the module file is 1.17, which is old enough to be worth noting. It does not stop the tool from building on a current toolchain, but it is a sign that the module dependencies have not been revisited in a while.
A local server that borrows GitHub's stylesheet
There are two moving parts and it is worth separating them, because they have different failure modes.
The first is the server. It binds a host and a port on localhost, serves the rendered document, and holds a websocket open for the reload signal. The default port is 3333 and the default host is localhost, and the auto find port behaviour means the command will move on if 3333 is taken. The auto open behaviour launches your browser at that address.
The second is the rendering, which happens elsewhere. The HTML comes from GitHub's official markdown API and the CSS is extracted from the GitHub website, which is what makes the preview look the same as the real thing.
The consequence is that this is not an offline tool. The fidelity depends on a network round trip to GitHub, and the README's claim of zero configuration is about credentials rather than about connectivity. The feature list says you do not have to set the GitHub access token, and the description says the command renders the HTML it got from GitHub's official markdown API. So a preview of a private document still involves sending that document to GitHub to be rendered, which for a security conscious team is a fact to know rather than a defect.
The other consequence is the reverse of the usual one. A preview built this way cannot disagree with GitHub about how the Markdown renders, because there is only one renderer involved. The cost is that you cannot preview offline, and you cannot preview Markdown that GitHub would not render.
The related projects, and the difference in approach
The README lists three related projects: the GitHub CLI itself, Grip, and github-markdown-css.
The GitHub CLI is the host this extension runs inside, so it is not really an alternative to it. github-markdown-css is a stylesheet project, and the interesting thing about it is that it is the same idea as this tool's styling half: taking the CSS that GitHub uses so that a local render looks right. That is precisely what this extension does with the CSS extracted from the GitHub website, which is why the README points at it.
Grip is the other related project, and the difference in approach is the interesting one. A local renderer parses the Markdown on your own machine and applies your own or a borrowed stylesheet, which means it works offline and can be themed, and it can disagree with GitHub about the details of the rendering. This extension goes the other way and asks GitHub to do the parsing, which is why the README can claim the styles are almost the same.
So the choice is between fidelity and locality. If the question is what will this look like on GitHub, this extension answers it exactly, and it answers it over the network. If the question is to iterate on a long document quickly, on a plane, or inside a network where GitHub is not reachable, a local renderer is the better tool, and the README's list is where you would start looking for one.
For most people writing a README, the fidelity is what they are after, because the whole point of the preview is to catch the thing GitHub will render differently from what they expected.
A single Go binary, released with goreleaser
The repository layout is small, which is what a tool like this should be. There is main.go, a cmd/ directory, the gh-markdown-preview directory, go.mod and go.sum, a testdata/ directory, a .goreleaser.yml file, the LICENSE and the README.
The .goreleaser.yml file is the release machinery. goreleaser is the standard Go tool for cutting tagged releases across platforms, and its presence tells you the binaries for Windows, macOS and Linux are built and published from a single configuration rather than by hand.
The testdata/ directory is where the fixtures live, which for a rendering tool means sample Markdown documents and probably the expected output, so that a change in how the extension renders something is caught by the test suite. The main.go and cmd/ split is the usual Go layout with the entry point at the root and the command implementation under cmd/.
The licence is MIT, distributed under the MIT License, and the author is Yusuke Wada. The recent releases are v1.12.0 on 2026-10-13, v1.11.2 on 2026-08-30 and v1.11.1 on 2026-05-21, with the last push to the repository on 2026-10-13, the same day as the newest tag.
The version numbering is worth a glance too, since the project is on a 1.x line with a minor bump every few months, which is a pace that suggests regular maintenance rather than a project that has been abandoned. The one stale number in the tree is the Go version in go.mod, still at 1.17.
Editorial conclusion
Adopt gh markdown-preview if you write documentation in Markdown and want to know how it will look on GitHub before you push it, and if you are happy for the preview to be rendered by GitHub's API over the network. Do not adopt it as an offline renderer or as a general Markdown to HTML converter, because the fidelity comes from Gitub's own rendering rather than from a local parser. Before you rely on it, check that your Markdown is served from a public or reachable endpoint, remember that the default preview reflects the gfm mode unless you force markdown mode, and if you need a fully local render with your own CSS, look at the related projects the README lists instead.
Frequently asked questions
What does the gh markdown-preview extension do?
It is a GitHub CLI extension that starts a local web server to serve a Markdown document, rendering the HTML returned by GitHub's official markdown API and using CSS extracted from the GitHub website, so the preview looks the same as the real thing.
How do I install gh markdown-preview?
With gh extension install yusukebe/gh-markdown-preview, and gh extension upgrade markdown-preview to upgrade it. You need the gh command and nothing else, and the README states there is zero configuration because you do not have to set a GitHub access token.
How do I preview a Markdown file that is not named README.md?
Pass the file name as the argument, for example gh markdown-preview README.md, or pipe the content in with echo or cat, or use gh markdown-preview - < README.md. With no argument at all the command detects the README file in the current directory.
What options does gh markdown-preview support?
Nine flags: --dark-mode, --markdown-mode, --disable-auto-open, --disable-reload, --help, --host, --light-mode, --port and --verbose, plus --version. The rendering mode defaults to gfm, the host defaults to localhost and the port to 3333.
Does gh markdown-preview work offline?
No. The HTML comes from GitHub's official markdown API and the styles are taken from the GitHub website, so the preview needs to reach GitHub to render. The README lists Grip and github-markdown-css as related projects for a local rendering approach.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yusukebe-gh-markdown-preview)Was this useful?