{"id":13783955,"url":"https://github.com/remarkjs/remark-git-contributors","last_synced_at":"2025-04-13T17:42:31.690Z","repository":{"id":46105656,"uuid":"135895427","full_name":"remarkjs/remark-git-contributors","owner":"remarkjs","description":"plugin to generate a list of Git contributors","archived":false,"fork":false,"pushed_at":"2024-09-23T12:38:48.000Z","size":179,"stargazers_count":13,"open_issues_count":0,"forks_count":5,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-06T08:43:19.142Z","etag":null,"topics":["community","contributors","git","markdown","remark","remark-plugin","social","tooling"],"latest_commit_sha":null,"homepage":"https://unifiedjs.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remarkjs.png","metadata":{"funding":{"github":"unifiedjs","open_collective":"unified"},"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-03T10:44:28.000Z","updated_at":"2024-09-23T15:29:48.000Z","dependencies_parsed_at":"2023-12-19T03:03:34.128Z","dependency_job_id":"d382b215-49c3-4e49-9825-06b476e83b0a","html_url":"https://github.com/remarkjs/remark-git-contributors","commit_stats":{"total_commits":135,"total_committers":2,"mean_commits":67.5,"dds":0.4296296296296296,"last_synced_commit":"3b0c0c548e2352d4fc3608e34628c64cb7bd7ee0"},"previous_names":["vweevers/remark-gh-contributors"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-git-contributors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-git-contributors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-git-contributors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-git-contributors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remarkjs","download_url":"https://codeload.github.com/remarkjs/remark-git-contributors/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248755955,"owners_count":21156680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["community","contributors","git","markdown","remark","remark-plugin","social","tooling"],"created_at":"2024-08-03T19:00:33.566Z","updated_at":"2025-04-13T17:42:31.656Z","avatar_url":"https://github.com/remarkjs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/unifiedjs","https://opencollective.com/unified"],"categories":["Plugins"],"sub_categories":[],"readme":"# remark-git-contributors\n\n[![Version][version-badge]][version]\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\n**[remark][]** plugin to generate a list of Git contributors.\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`defaultFilter(contributor, metadata)`](#defaultfiltercontributor-metadata)\n  * [`unified().use(remarkGitContributors[, options])`](#unifieduseremarkgitcontributors-options)\n  * [`Contributor`](#contributor)\n  * [`Filter`](#filter)\n  * [`Options`](#options)\n* [Examples](#examples)\n  * [Example: CLI](#example-cli)\n  * [Example: CLI in npm scripts](#example-cli-in-npm-scripts)\n  * [Example: `appendIfMissing`](#example-appendifmissing)\n  * [Example: metadata](#example-metadata)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [Contributors](#contributors)\n* [License](#license)\n\n## What is this?\n\nThis package is a [unified][] ([remark][]) plugin that collects contributors\nfrom Git history, deduplicates them, augments it with metadata found in options,\na module, or `package.json`, and passes that to\n[`remark-contributors`][remark-contributors] to add them in a table in\n`## Contributors`.\n\n## When should I use this?\n\nThis project is particularly useful when you have (open source) projects that\nare maintained with Git and want to show who helped build them by adding their\nnames, websites, and perhaps some more info, based on their commits, to readmes.\nThis package is useful because it’s automated based on Git: those who commit\nwill get included.\nThe downside is that commits aren’t the only way to contribute (something\n[All Contributors][all-contributors] focusses on).\n\nThis plugin is a Git layer on top of\n[`remark-contributors`][remark-contributors], so it shares its benefits.\nYou can also use that plugin when you don’t want Git commits to be the source of\ntruth.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install remark-git-contributors\n```\n\nContributions are welcome to add support for Deno.\n\n## Use\n\nSay we have the following file `example.md` in this project:\n\n```markdown\n# Example\n\nSome text.\n\n## Contributors\n\n## License\n\nMIT\n```\n\n…and a module `example.js`:\n\n```js\nimport {remark} from 'remark'\nimport remarkGfm from 'remark-gfm'\nimport remarkGitContributors from 'remark-git-contributors'\nimport {read} from 'to-vfile'\n\nconst file = await remark()\n  .use(remarkGfm) // Required: add support for tables (a GFM feature).\n  .use(remarkGitContributors)\n  .process(await read('example.md'))\n\nconsole.log(String(file))\n```\n\n…then running `node example.js` yields:\n\n```markdown\n# Example\n\nSome text.\n\n## Contributors\n\n| Name                | GitHub                                       | Social                                                |\n| :------------------ | :------------------------------------------- | :---------------------------------------------------- |\n| **Titus Wormer**    | [**@wooorm**](https://github.com/wooorm)     | [**@wooorm@twitter**](https://twitter.com/wooorm)     |\n| **Vincent Weevers** | [**@vweevers**](https://github.com/vweevers) | [**@vweevers@twitter**](https://twitter.com/vweevers) |\n\n## License\n\nMIT\n```\n\n\u003e 👉 **Note**: These contributors are inferred from the Git history\n\u003e and [`package.json`][file-package-json] in this repo.\n\u003e Running this example in a different package will yield different results.\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`remarkGitContributors`][api-remark-git-contributors].\n\n### `defaultFilter(contributor, metadata)`\n\nDefault filter for contributors ([`Filter`][api-filter]);\ncurrently filters out Greenkeeper.\n\n### `unified().use(remarkGitContributors[, options])`\n\nGenerate a list of Git contributors.\n\nIn short, this plugin:\n\n* looks for the first heading matching `/^contributors$/i`\n* if no heading is found and `appendIfMissing` is set, injects such a heading\n* if there is a heading, replaces everything in that section with a new table\n  with Git contributors\n\n###### Parameters\n\n* `options` ([`Options`][api-options] or `string`, optional)\n  — configuration;\n  passing `string` is as if passing `options.contributors`\n\n###### Returns\n\nTransform ([`Transformer`][unified-transformer]).\n\n### `Contributor`\n\nContributor in string form (`name \u003cemail\u003e (url)`) or as object (TypeScript\ntype).\n\n###### Type\n\n```ts\ntype Contributor = Record\u003cstring, unknown\u003e | string\n```\n\n### `Filter`\n\nFilter contributors (TypeScript type).\n\n###### Parameters\n\n* `contributor` (`Contributor`)\n  — contributor found by `contributorsFromGit`\n* `metadata` (`Record\u003cstring, unknown\u003e`)\n  — associated metadata found in `package.json` or `options.contributors`\n\n###### Returns\n\nWhether to include the contributor (`boolean`).\n\n### `Options`\n\nConfiguration (TypeScript type).\n\n###### Fields\n\n* `appendIfMissing` (`boolean`, default: `false`)\n  — inject the section if there is none\n* `contributors` ([`Array\u003cContributor\u003e`][api-contributor] or `string`,\n  optional)\n  — list of contributors to inject;\n  defaults to the `contributors` field in the closest `package.json` upwards\n  from the processed file, if there is one;\n  supports the string form (`name \u003cemail\u003e (url)`) as well;\n  throws if no contributors are found or given\n* `cwd` (`string`, default: `file.cwd`)\n  — working directory from which to resolve a `contributors` module, if any\n* `filter` ([`Filter`][api-filter], default:\n  [`defaultFilter`][api-default-filter])\n  — filter contributors\n* `limit` (`number`, default: `0`)\n  — limit the rendered contributors;\n  `0` (or lower) includes all contributors;\n  if `limit` is given, only the top `\u003climit\u003e` contributors, sorted by commit\n  count, are rendered\n\n## Examples\n\n### Example: CLI\n\nIt’s recommended to use `remark-git-contributors` on the CLI with\n[`remark-cli`][remark-cli].\nInstall both (and [`remark-gfm`][remark-gfm]) with [npm][]:\n\n```sh\nnpm install remark-cli remark-gfm remark-git-contributors --save-dev\n```\n\nLet’s say we have an `example.md` with the following text:\n\n```markdown\n# Hello\n\nSome text.\n\n## Contributors\n```\n\nYou can now use the CLI to format `example.md`:\n\n```sh\nnpx remark --output --use remark-gfm --use remark-git-contributors example.md\n```\n\nThis adds the table of contributors to `example.md`, which now contains (when\nrunning in this project):\n\n```markdown\n# Hello\n\nSome text.\n\n## Contributors\n\n| Name                | GitHub                                       | Social                                                |\n| :------------------ | :------------------------------------------- | :---------------------------------------------------- |\n| **Titus Wormer**    | [**@wooorm**](https://github.com/wooorm)     | [**@wooorm@twitter**](https://twitter.com/wooorm)     |\n| **Vincent Weevers** | [**@vweevers**](https://github.com/vweevers) | [**@vweevers@twitter**](https://twitter.com/vweevers) |\n```\n\n### Example: CLI in npm scripts\n\nYou can use `remark-git-contributors` and [`remark-cli`][remark-cli] in an npm\nscript to format markdown in your project.\nInstall both (and [`remark-gfm`][remark-gfm]) with [npm][]:\n\n```sh\nnpm install remark-cli remark-gfm remark-git-contributors --save-dev\n```\n\nThen, add a format script and configuration to `package.json`:\n\n```js\n{\n  // …\n  \"scripts\": {\n    // …\n    \"format\": \"remark . --output --quiet\",\n    // …\n  },\n  \"remarkConfig\": {\n    \"plugins\": [\n      \"remark-gfm\",\n      \"remark-git-contributors\"\n    ]\n  },\n  // …\n}\n```\n\n\u003e 💡 **Tip**: Add other tools such as prettier or ESLint to check and format\n\u003e other files.\n\u003e\n\u003e 💡 **Tip**: Run `./node_modules/.bin/remark --help` for help with\n\u003e `remark-cli`.\n\nNow you format markdown in your project with:\n\n```sh\nnpm run format\n```\n\n### Example: `appendIfMissing`\n\nThe default behavior of this plugin is to not generate lists of Git\ncontributors if there is no `## Contributors` (case- and level-insensitive).\nYou can change that by configuring the plugin with\n`options.appendIfMissing: true`.\n\nThe reason for not generating contributors by default is that as we saw in the\nprevious example (CLI in npm scripts) remark and this plugin often run on\nseveral files.\nYou can choose where to add the list by explicitly adding `## Contributors`\nin the main file (`readme.md`) and other docs won’t be touched.\nOr, when you have many contributors, add a specific `contributors.md` file,\nwith a primary `# Contributors` heading, and the list will be generated there.\n\nTo turn `appendIfMissing` mode on, pass it like so on the API:\n\n```js\n  // …\n  .use(remarkGitContributors, {appendIfMissing: true})\n  // …\n```\n\nOr on the CLI (in `package.json`):\n\n```js\n  // …\n  \"remarkConfig\": {\n    \"plugins\": [\n      // …\n      [\n        \"remark-git-contributors\",\n        {\"appendIfMissing\": true}\n      ]\n    ]\n  },\n  // …\n```\n\n### Example: metadata\n\nThe data gathered from Git is only includes names and emails.\nTo add more metadata, either add it to `package.json` (used in this project’s\n[`package.json`][file-package-json]) or configure `options.contributors`.\nOn the API, that’s done like so:\n\n```js\n  // …\n  .use(remarkGitContributors, {contributors: /* value */})\n  // …\n```\n\nOr on the CLI (in `package.json`):\n\n```js\n  // …\n  \"remarkConfig\": {\n    \"plugins\": [\n      // …\n      [\n        \"remark-git-contributors\",\n        {\"contributors\": /* value */}\n      ]\n    ]\n  },\n  // …\n```\n\nThe value for `contributors` is either:\n\n* an array in the form of `[{ email, name, … }, … ]`;\n* a module id, or path to a file, that exports `contributors` as the default\n  export or as a `contributors` named export\n\n\u003e 👉 **Note**: contributors that are not in Git history are excluded.\n\u003e This way the `contributors` metadata can be reused in multiple projects.\n\nEach contributor should at least have an `email` property to match against Git\nemail addresses.\nIf you’re experiencing people showing up multiple times from Git history, for\nexample because they switched email addresses while contributing to the project,\nor if their name or email are wrong, you can “merge” and fix contributors in Git\nby using a [`.mailmap` file][git-mailmap].\n\nThe supported properties on contributors are:\n\n* `email` — person’s email (example: `sara@example.com`)\n* `github` — GitHub username (example: `sara123`)\n* `mastodon` — Mastodon (`@user@domain`)\n* `name` — person’s name (example: `Sara`)\n* `twitter` — Twitter username (example: `the_sara`)\n\nAn example of a module is:\n\n```js\n  // …\n  .use(remarkGitContributors, {contributors: './data/contributors.js'})\n  // …\n```\n\nWhere `data/contributors.js` would contain either:\n\n```js\nexport const contributors = [{ email, name, /* … */ }, /* … */ ]\n```\n\nOr:\n\n```js\nconst contributors = [{ email, name, /* … */ }, /* … */ ]\n\nexport default contributors\n```\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types\n[`Contributor`][api-contributor],\n[`Filter`][api-filter], and\n[`Options`][api-options].\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line,\n`remark-git-contributors@^5`, compatible with Node.js 16.\n\nThis plugin works with `unified` version 6+ and `remark` version 7+.\n\n## Security\n\n`remark-git-contributors` is typically used in a trusted environment.\nThis section explains potential attack vectors and how to mitigate them if the\nenvironment is not (fully) trusted.\n\n`options.contributors` (or `contributors` in `package.json`) and `author` from\n`package.json` are used and injected into the tree.\n`git log` also runs in the current working directory.\nThis could open you up to a [cross-site scripting (XSS)][wiki-xss] attack if\nyou pass user provided content in or store user provided content in\n`package.json` or Git.\n\nThis may become a problem if the markdown later transformed to **[rehype][]**\n(**[hast][]**) or opened in an unsafe markdown viewer.\n\nIf `contributors` is a string, it is handled as a module identifier and\nimported.\nThis could also be very dangerous if an attacker was able to inject code in that\npackage.\n\n## Contribute\n\nSee [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways\nto get started.\nSee [`support.md`][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## Contributors\n\n| Name                | GitHub                                       | Social                                                |\n| :------------------ | :------------------------------------------- | :---------------------------------------------------- |\n| **Titus Wormer**    | [**@wooorm**](https://github.com/wooorm)     | [**@wooorm@twitter**](https://twitter.com/wooorm)     |\n| **Vincent Weevers** | [**@vweevers**](https://github.com/vweevers) | [**@vweevers@twitter**](https://twitter.com/vweevers) |\n\n## License\n\n[MIT][license] © Vincent Weevers\n\n\u003c!-- Definitions --\u003e\n\n[version-badge]: http://img.shields.io/npm/v/remark-git-contributors.svg\n\n[version]: https://www.npmjs.org/package/remark-git-contributors\n\n[build-badge]: https://github.com/remarkjs/remark-git-contributors/workflows/main/badge.svg\n\n[build]: https://github.com/remarkjs/remark-git-contributors/actions\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-git-contributors.svg\n\n[coverage]: https://codecov.io/github/remarkjs/remark-git-contributors\n\n[downloads-badge]: https://img.shields.io/npm/dm/remark-git-contributors.svg\n\n[downloads]: https://www.npmjs.com/package/remark-git-contributors\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[collective]: https://opencollective.com/unified\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[chat]: https://github.com/remarkjs/remark/discussions\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[health]: https://github.com/remarkjs/.github\n\n[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md\n\n[support]: https://github.com/remarkjs/.github/blob/main/support.md\n\n[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md\n\n[license]: license\n\n[all-contributors]: https://github.com/all-contributors/all-contributors\n\n[git-mailmap]: https://git-scm.com/docs/git-shortlog#_mapping_authors\n\n[hast]: https://github.com/syntax-tree/hast\n\n[remark]: https://github.com/remarkjs/remark\n\n[rehype]: https://github.com/rehypejs/rehype\n\n[remark-cli]: https://github.com/remarkjs/remark/tree/main/packages/remark-cli\n\n[remark-contributors]: https://github.com/remarkjs/remark-contributors\n\n[remark-gfm]: https://github.com/remarkjs/remark-gfm\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://github.com/unifiedjs/unified\n\n[unified-transformer]: https://github.com/unifiedjs/unified#transformer\n\n[wiki-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting\n\n[file-package-json]: package.json\n\n[api-contributor]: #contributor\n\n[api-default-filter]: #defaultfiltercontributor-metadata\n\n[api-filter]: #filter\n\n[api-options]: #options\n\n[api-remark-git-contributors]: #unifieduseremarkgitcontributors-options\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Fremark-git-contributors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremarkjs%2Fremark-git-contributors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Fremark-git-contributors/lists"}