Installation
+ +macOS (manual installation):
+curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
+chmod a+x gh-md-toc
+
+Linux (manual installation):
+wget https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc
+chmod a+x gh-md-toc
+
+Linux or macOS, using Basher (gh-md-toc will be available in the PATH):
basher install ekalinin/github-markdown-toc
+
+Why
+ +gh-md-toc is for you if you want to generate a TOC (table of contents) for a README.md or a GitHub wiki page without installing additional software. It is an attempt to fix the problem from github/issues/215.
+ +It needs only standard tools:
+-
+
curlorwget
+ awk
+ grep
+ sed
+
Usage
+ +gh-md-toc works with markdown from stdin, local files, and pages on github.com. Local files and stdin are rendered through the GitHub API, see GitHub token if you hit its rate limit.
+ +STDIN
+ +Pass - to read markdown from stdin:
$ cat README.md | ./gh-md-toc -
+* [gh-md-toc](#gh-md-toc)
+* [Table of contents](#table-of-contents)
+* [Installation](#installation)
+* [Usage](#usage)
+ * [STDIN](#stdin)
+ * [Local files](#local-files)
+ * [Remote files](#remote-files)
+ * [Multiple files](#multiple-files)
+...
+
+Local files
+ +Pass a path to a markdown file:
+$ ./gh-md-toc README.md
+
+Table of Contents
+=================
+
+* [gh-md-toc](#gh-md-toc)
+* [Table of contents](#table-of-contents)
+* [Installation](#installation)
+* [Usage](#usage)
+ * [STDIN](#stdin)
+ * [Local files](#local-files)
+...
+* [Docker](#docker)
+ * [Local](#local)
+ * [Public](#public)
+
+<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
+
+Remote files
+ +Pass a URL instead of a path, for example a GitHub wiki page:
+$ ./gh-md-toc https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv
+
+Table of Contents
+=================
+
+* [Who Uses Nodeenv?](#who-uses-nodeenv)
+ * [edx](#edx)
+ * [OpenStack](#openstack)
+ * [HSReplay.net](#hsreplaynet)
+ * [pre-commit.com](#pre-commitcom)
+ * [sailing-channels.com](#sailing-channelscom)
+ * [Galaxy](#galaxy)
+ * [Lambdas in Python with Serverless.com](#lambdas-in-python-with-serverlesscom)
+
+<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
+
+That's all. Copy the result into your README.md, or redirect it to a file with > toc.md.
Multiple files
+ +Pass several files or URLs, local and remote ones can be combined. Each link is prefixed with its source:
+$ ./gh-md-toc README.md https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv
+
+* [gh-md-toc](README.md#gh-md-toc)
+* [Table of contents](README.md#table-of-contents)
+* [Installation](README.md#installation)
+...
+ * [Public](README.md#public)
+
+* [Who Uses Nodeenv?](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#who-uses-nodeenv)
+ * [edx](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#edx)
+ * [OpenStack](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#openstack)
+ * [HSReplay.net](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#hsreplaynet)
+ * [pre-commit.com](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#pre-commitcom)
+ * [sailing-channels.com](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#sailing-channelscom)
+ * [Galaxy](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#galaxy)
+ * [Lambdas in Python with Serverless.com](https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv#lambdas-in-python-with-serverlesscom)
+
+<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
+
+Auto insert and update TOC
+ +Put these two lines into a local file where the TOC should be:
+<!--ts-->
+<!--te-->
+
+And run:
+$ ./gh-md-toc --insert README.md
+
+Table of Contents
+=================
+
+* [My project](#my-project)
+ * [Installation](#installation)
+ * [Usage](#usage)
+ * [Options](#options)
+ * [License](#license)
+Found markers
+
+!! TOC was added into: 'README.md'
+!! Origin version of the file: 'README.md.orig.2026-09-27_112342'
+!! TOC added into a separate file: 'README.md.toc.2026-09-27_112342'
+
+
+<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
+
+The file now contains:
+<!--ts-->
+* [My project](#my-project)
+ * [Installation](#installation)
+ * [Usage](#usage)
+ * [Options](#options)
+ * [License](#license)
+
+<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
+<!-- Added by: user, at: Sun Sep 27 11:23:42 UTC 2026 -->
+
+<!--te-->
+
+When the file changes, run the same command again to refresh the TOC. Options for --insert:
-
+
--no-backup- do not keep the backup files (.orig.*and.toc.*).
+ --hide-footer- do not write the footer comments with the author and date of the last TOC update.
+
GitHub Actions
+ +Keep the TOC up to date on every push to the file:
+on:
+ push:
+ branches: [main]
+ paths: ['foo.md']
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v7
+ - run: |
+ curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
+ chmod a+x gh-md-toc
+ ./gh-md-toc --insert --no-backup --hide-footer foo.md
+ rm gh-md-toc
+ - uses: stefanzweifel/git-auto-commit-action@v7
+ with:
+ commit_message: Auto update markdown TOC
+
+permissions: contents: write lets the default GITHUB_TOKEN push the updated file.
GitHub token
+ +Without a token, the GitHub API limits how many files you can process per hour. When you hit the limit, gh-md-toc prints:
+Parsing local markdown file requires access to github API
+Error: You exceeded the hourly limit. See: https://developer.github.com/v3/#rate-limiting
+or place GitHub auth token here: /home/user/token.txt
+
+Create a token at github.com/settings/tokens and pass it as an environment variable:
+GH_TOC_TOKEN=<your token> ./gh-md-toc README.md
+
+Or put it into token.txt next to the gh-md-toc script:
echo "<your token>" > token.txt
+./gh-md-toc README.md
+
+Docker
+ +Public image on Docker Hub:
+docker pull evkalinin/gh-md-toc:{{VERSION}}
+docker run -it evkalinin/gh-md-toc:{{VERSION}} https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv
+
+Or build the image from the repository's Dockerfile:
docker build -t markdown-toc-generator .
+
+Run it on a URL:
+docker run -it markdown-toc-generator https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv
+
+Run it on a local file, sharing its directory as a volume:
+docker run -it -v "$PWD":/data markdown-toc-generator /data/README.md
+
+Windows
+ +gh-md-toc is a Bash script. On Windows, use github-markdown-toc.go, a Go implementation without dependencies that can also process files in parallel.
+ +