{"id":13476294,"url":"https://github.com/tcort/markdown-link-check","last_synced_at":"2025-05-13T23:03:57.896Z","repository":{"id":38693619,"uuid":"49756018","full_name":"tcort/markdown-link-check","owner":"tcort","description":"checks all of the hyperlinks in a markdown text to determine if they are alive or dead","archived":false,"fork":false,"pushed_at":"2025-05-05T14:38:38.000Z","size":1121,"stargazers_count":620,"open_issues_count":82,"forks_count":124,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-08T19:27:37.199Z","etag":null,"topics":["checker","hyperlinks","markdown"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tcort.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-01-16T02:41:09.000Z","updated_at":"2025-05-08T07:14:52.000Z","dependencies_parsed_at":"2024-01-17T16:06:59.567Z","dependency_job_id":"c7213077-db6f-4baa-b531-e95eec2f36b7","html_url":"https://github.com/tcort/markdown-link-check","commit_stats":{"total_commits":250,"total_committers":43,"mean_commits":5.813953488372093,"dds":0.404,"last_synced_commit":"bfee3ac6af5eab3acb4155db011e51413b734e44"},"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tcort%2Fmarkdown-link-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tcort%2Fmarkdown-link-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tcort%2Fmarkdown-link-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tcort%2Fmarkdown-link-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tcort","download_url":"https://codeload.github.com/tcort/markdown-link-check/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254040355,"owners_count":22004515,"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":["checker","hyperlinks","markdown"],"created_at":"2024-07-31T16:01:28.673Z","updated_at":"2025-05-13T23:03:57.885Z","avatar_url":"https://github.com/tcort.png","language":"JavaScript","readme":"[![Releases](https://img.shields.io/github/v/tag/tcort/markdown-link-check.svg?sort=semver)](https://github.com/tcort/markdown-link-check/releases)\n[![Stars](https://img.shields.io/github/stars/tcort/markdown-link-check)](https://github.com/tcort/markdown-link-check/stargazers)\n[![Forks](https://img.shields.io/github/forks/tcort/markdown-link-check)](https://github.com/tcort/markdown-link-check/network/members)\n[![Test library workflow status](https://github.com/tcort/markdown-link-check/actions/workflows/ci.yml/badge.svg)](https://github.com/tcort/markdown-link-check/actions/workflows/ci.yml)\n[![License](https://img.shields.io/github/license/tcort/markdown-link-check)](https://github.com/tcort/markdown-link-check/blob/master/LICENSE.md)\n\n# markdown-link-check\n\nExtracts links from markdown texts and checks whether each link is\nalive (`200 OK`) or dead. `mailto:` links are also validated.\n\n## Installation\n\nTo add the module to your project, run:\n\n```shell\nnpm install --save-dev markdown-link-check\n```\n\nTo install the command line tool globally, run:\n\n```shell\nnpm install -g markdown-link-check\n```\n\n---\n\n## Run using Docker\n\nDocker images are built with each release. Use the `stable` tag for the current stable release.\n\nAdd current directory with your `README.md` file as read only volume to `docker run`:\n\n```shell\ndocker run -v .:/tmp:ro --rm -i ghcr.io/tcort/markdown-link-check:stable /tmp/README.md\n```\n\nAlternatively, if you wish to target a specific release, images are tagged with semantic versions (i.e. `3`, `3.8`, `3.8.3`)\n\n## Run in a GitHub action\n\nPlease head on to [github-action-markdown-link-check](https://github.com/tcort/github-action-markdown-link-check).\n\n## Run as a pre-commit hook\n\nTo run as a [pre-commit hook](https://pre-commit.com):\n\n```\n- repo: https://github.com/tcort/markdown-link-check\n  rev: ...\n  hooks:\n    - id: markdown-link-check\n      args: [-q]\n```\n\n## Run in a GitLab pipeline\n\n```yaml\nlinkchecker:\n  stage: test\n  image:\n    name: ghcr.io/tcort/markdown-link-check:3.11.2\n    entrypoint: [\"/bin/sh\", \"-c\"]\n  script:\n    - markdown-link-check ./docs\n  rules:\n    - changes:\n      - \"**/*.md\"\n```\n\n## Run in other tools\n\n- [Mega-Linter](https://megalinter.io/latest/): Linters aggregator [including markdown-link-check](https://megalinter.io/latest/descriptors/markdown_markdown_link_check/)\n\n## API\n\n### markdownLinkCheck(markdown, [opts,] callback)\n\nGiven a string containing `markdown` formatted text and a `callback`,\nextract all of the links and check if they're alive or dead. Call the\n`callback` with `(err, results)`\n\nParameters:\n\n* `markdown` string containing markdown formatted text.\n* `opts` optional options object containing any of the following optional fields:\n  * `showProgressBar` enable an ASCII progress bar.\n  * `timeout` timeout in [ms](https://www.npmjs.com/package/ms) format. (e.g. `\"2000ms\"`, `20s`, `1m`). Default `10s`.\n  * `httpHeaders` to apply URL specific headers, see example below.\n  * `ignorePatterns` an array of objects holding regular expressions which a link is checked against and skipped for checking in case of a match. Example: `[{ pattern: /foo/ }]`\n  * `replacementPatterns` an array of objects holding regular expressions which are replaced in a link with their corresponding replacement string. This behavior allows (for example) to adapt to certain platform conventions hosting the Markdown. The special replacement `{{BASEURL}}` can be used to dynamically link to the base folder (used from `projectBaseUrl`) (for example that `/` points to the root of your local repository). Example: `[{ pattern: /^.attachments/, replacement: \"file://some/conventional/folder/.attachments\" }, { pattern: ^/, replacement: \"{{BASEURL}}/\"}]`. You can add `\"global\": true` to use a global regular expression to replace all instances.\n  * `projectBaseUrl` the URL to use for `{{BASEURL}}` replacement\n  * `ignoreDisable` if this is `true` then disable comments are ignored.\n  * `retryOn429` if this is `true` then retry request when response is an HTTP code 429 after the duration indicated by `retry-after` header.\n  * `retryCount` the number of retries to be made on a 429 response. Default `2`.\n  * `fallbackRetryDelay` the delay in [ms](https://www.npmjs.com/package/ms) format. (e.g. `\"2000ms\"`, `20s`, `1m`) for retries on a 429 response when no `retry-after` header is returned or when it has an invalid value. Default is `60s`.\n  * `aliveStatusCodes` a list of HTTP codes to consider as alive.\n    Example: `[200,206]`\n* `callback` function which accepts `(err, results)`.\n  * `err` an Error object when the operation cannot be completed, otherwise `null`.\n  * `results` an array of objects with the following properties:\n    * `link` the `link` provided as input\n    * `status` a string set to either `alive`, `ignored` or `dead`.\n    * `statusCode` the HTTP status code. Set to `0` if no HTTP status code was returned (e.g. when the server is down).\n    * `err` any connection error that occurred, otherwise `null`.\n\n#### Disable comments\n\nYou can write html comments to disable markdown-link-check for parts of the text.\n\n`\u003c!-- markdown-link-check-disable --\u003e` disables markdown link check.\n`\u003c!-- markdown-link-check-enable --\u003e` reenables markdown link check.\n`\u003c!-- markdown-link-check-disable-next-line --\u003e` disables markdown link check for the next line.\n`\u003c!-- markdown-link-check-disable-line --\u003e` disables markdown link check for this line.\n\n## Examples\n\n### Module\n\n**Basic usage:**\n\n```js\n'use strict';\n\nvar markdownLinkCheck = require('markdown-link-check');\n\nmarkdownLinkCheck('[example](http://example.com)', function (err, results) {\n    if (err) {\n        console.error('Error', err);\n        return;\n    }\n    results.forEach(function (result) {\n        console.log('%s is %s', result.link, result.status);\n    });\n});\n```\n\n**With options, for example using URL specific headers:**\n\n```js\n'use strict';\n\nvar markdownLinkCheck = require('markdown-link-check');\n\nmarkdownLinkCheck('[example](http://example.com)', { httpHeaders: [{ urls: ['http://example.com'], headers: { 'Authorization': 'Basic Zm9vOmJhcg==' }}] }, function (err, results) {\n    if (err) {\n        console.error('Error', err);\n        return;\n    }\n    results.forEach(function (result) {\n        console.log('%s is %s', result.link, result.status);\n    });\n});\n```\n\n### Command Line Tool\n\nThe command line tool optionally takes 1 argument, the file name or http/https URL.\nIf not supplied, the tool reads from standard input.\n\n#### Check links from a markdown file hosted on the web\n\n```shell\nmarkdown-link-check https://github.com/tcort/markdown-link-check/blob/master/README.md\n```\n\n#### Check links from a local markdown file\n\n```shell\nmarkdown-link-check ./README.md\n```\n\n#### Check links from a local markdown folder (recursive)\n\nThis checks all files in folder `./docs` with file extension `*.md`:\n\n```shell\nmarkdown-link-check ./docs\n```\n\nThe files can also be searched for and filtered manually:\n\n```shell\nfind . -name \\*.md -print0 | xargs -0 -n1 markdown-link-check\n```\n\n#### Usage\n\n```shell\nUsage: markdown-link-check [options] [filenamesOrDirectorynamesOrUrls...]\n\nOptions:\n  -V, --version           output the version number\n  -p, --progress          show progress bar\n  -c, --config [config]   apply a config file (JSON), holding e.g. url specific header configuration\n  -q, --quiet             displays errors only\n  -v, --verbose           displays detailed error information\n  -i, --ignore \u003cpaths\u003e    ignore input paths including an ignore path\n  -a, --alive \u003ccode\u003e      comma separated list of HTTP codes to be considered as alive\n  -r, --retry             retry after the duration indicated in 'retry-after' header when HTTP code is 429\n  --reporters \u003cnames\u003e     specify reporters to use\n  --projectBaseUrl \u003curl\u003e  the URL to use for {{BASEURL}} replacement\n  -h, --help              display help for command\n```\n\n##### Config file format\n\n`config.json`:\n\n* `ignorePatterns`: An array of objects holding regular expressions which a link is checked against and skipped for checking in case of a match.\n* `replacementPatterns`: An array of objects holding regular expressions which are replaced in a link with their corresponding replacement string. This behavior allows (for example) to adapt to certain platform conventions hosting the Markdown. The special replacement `{{BASEURL}}` can be used to dynamically link to the current working directory (for example that `/` points to the root of your current working directory). This parameter supports named regex groups the same way as `string.replace` [method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) in node.\n* `httpHeaders`: The headers are only applied to links where the link **starts with** one of the supplied URLs in the `urls` section.\n* `timeout` timeout in [ms](https://www.npmjs.com/package/ms) format. (e.g. `\"2000ms\"`, `20s`, `1m`). Default `10s`.\n* `retryOn429` if this is `true` then retry request when response is an HTTP code 429 after the duration indicated by `retry-after` header.\n* `retryCount` the number of retries to be made on a 429 response. Default `2`.\n* `fallbackRetryDelay` the delay in [ms](https://www.npmjs.com/package/ms) format. (e.g. `\"2000ms\"`, `20s`, `1m`) for retries on a 429 response when no `retry-after` header is returned or when it has an invalid value. Default is `60s`.\n* `aliveStatusCodes` a list of HTTP codes to consider as alive.\n* `projectBaseUrl` the URL to use for `{{BASEURL}}` replacement\n\n**Example:**\n\n```json\n{\n  \"projectBaseUrl\":\"${workspaceFolder}\",\n  \"ignorePatterns\": [\n    {\n      \"pattern\": \"^http://example.net\"\n    }\n  ],\n  \"replacementPatterns\": [\n    {\n      \"pattern\": \"^.attachments\",\n      \"replacement\": \"file://some/conventional/folder/.attachments\"\n    },\n    {\n      \"pattern\": \"^/\",\n      \"replacement\": \"{{BASEURL}}/\"\n    },\n    {\n      \"pattern\": \"%20\",\n      \"replacement\": \"-\",\n      \"global\": true\n    },\n    {\n      \"pattern\": \"images/(?\u003cfilename\u003e.*)\",\n      \"replacement\": \"assets/$\u003cfilename\u003e\"\n    }\n  ],\n  \"httpHeaders\": [\n    {\n      \"urls\": [\"https://example.com\"],\n      \"headers\": {\n        \"Authorization\": \"Basic Zm9vOmJhcg==\",\n        \"Foo\": \"Bar\"\n      }\n    }\n  ],\n  \"timeout\": \"20s\",\n  \"retryOn429\": true,\n  \"retryCount\": 5,\n  \"fallbackRetryDelay\": \"30s\",\n  \"aliveStatusCodes\": [200, 206]\n}\n```\n\n## Testing\n\n```shell\nnpm test\n```\n\n## License\n\nSee [LICENSE.md](https://github.com/tcort/markdown-link-check/blob/master/LICENSE.md)\n","funding_links":[],"categories":["JavaScript","Documentation"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftcort%2Fmarkdown-link-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftcort%2Fmarkdown-link-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftcort%2Fmarkdown-link-check/lists"}