Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time



Automatically open a Github issue as blog comments for every articles of your blog. It also creates a gh-comments.json file to keep track of created issues for future executions and to open issues only for new articles.

This package is useful if you have a statically generated blog, such as Jekyll or Metalsmith, and you want to use Github issues as comments instead of the evil Disqus. For more details read Using and automating GitHub issues as blog comments or Replacing Disqus with Github Comments.


npm install gh-issues-for-comments --save


import ghComments from 'gh-issues-for-comments';

// Array of articles with any shape you like, for example obtained from Markdown files. 
// If you use default options each article must have 'id' and 'title' properties
const articles = [
  { id: 1, title: 'Hello world' }, 
  { id: 2, title: 'Hello world 2' }

ghComments(articles, {
  username: 'jiayihu',
  repo: 'blog',
  token: '123GithubOAuthToken',
  .then(createdIssues => console.log(createdIssues))
  .catch(error => console.error('Error with issues creation', error));


ghComments(articles, options): Promise

Create a Github issue for every article without a comments issue yet. Returns a Promise with the updated map with <article, issueId> pairs. It's the same object saved in gh-comments.json.

articles is an Array of articles objects with any shape. Each article will be used to return the data for its issue in getIssue(article) option.

options has the following shape:

  • options.username (required)

    Type: string

    Github username

  • options.repo (required)

    Type: string

    Github repository name

  • options.token (required)

    Type: string

    Github OAuth access token. Read here for more details. The only scope needed by the package is public_repo.

  • options.idProperty (optional)

    Type: string

    Default value: id

    Article property to use as unique id. If an id is not available, it's recommended to use something meaninful but not likely to change like the filepath or title.

  • options.jsonPath (optional)

    Type: string

    Default value: gh-comments.json

    Path to the JSON file where articles issue ids are stored

  • options.getIssue (optional)

    Type: Function

    Default value:

    function getIssue(article) {
      return {
        title: `Comments: ${article.title}`,
        body: `This issue is reserved for comments to **${article.title}**. Leave a comment below and it will be shown in the blog page.`,
        labels: ['comments'],

    Returns the issue data based on the article. If you want the article name, in the issue body, to be linked you can use the following value:

    function getIssue(article) {
      const formattedTitle = article.title.replace(/\s/g, '-').toLowerCase();
      const articleUrl = url.resolve('', formattedTitle);
      return {
        title: `Comments: ${article.title}`,
        body: `This issue is reserved for comments to [${article.title}](${articleUrl}). Leave a comment below and it will be shown in the blog page.`,
        labels: ['comments'],

Avoid issue creation

The script won't open an issue for an article if it finds an issueId in gh-comments.json for that article. So for example you can add the following content to skip issue creation for articles/angular-aot.html.

  "articles/angular-aot.html": {
    "issueId": -1


🐈 Automatically create Github issues to use as blog comments





No releases published


No packages published