diff --git a/doc/api/assert.md b/doc/api/assert.md
index 9ad01a48f0fd9a..0f88c1829d1350 100644
--- a/doc/api/assert.md
+++ b/doc/api/assert.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/assert.js -->
+
 The `assert` module provides a set of assertion functions for verifying
 invariants.
 
diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md
index bd721dc13af5d0..91c8c0e228658a 100644
--- a/doc/api/async_hooks.md
+++ b/doc/api/async_hooks.md
@@ -4,6 +4,8 @@
 
 > Stability: 1 - Experimental
 
+<!-- source_link=lib/async_hooks.js -->
+
 The `async_hooks` module provides an API to track asynchronous resources. It
 can be accessed using:
 
diff --git a/doc/api/buffer.md b/doc/api/buffer.md
index 3684e3169b7829..e61376841b0c71 100644
--- a/doc/api/buffer.md
+++ b/doc/api/buffer.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/buffer.js -->
+
 In Node.js, `Buffer` objects are used to represent binary data in the form
 of a sequence of bytes. Many Node.js APIs, for example streams and file system
 operations, support `Buffer`s, as interactions with the operating system or
diff --git a/doc/api/child_process.md b/doc/api/child_process.md
index ba29c0dc5f0490..cdfbd1517c9db3 100644
--- a/doc/api/child_process.md
+++ b/doc/api/child_process.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/child_process.js -->
+
 The `child_process` module provides the ability to spawn child processes in
 a manner that is similar, but not identical, to popen(3). This capability
 is primarily provided by the [`child_process.spawn()`][] function:
diff --git a/doc/api/cluster.md b/doc/api/cluster.md
index 3c67d4cf1ed371..1ed5e38670fb3c 100644
--- a/doc/api/cluster.md
+++ b/doc/api/cluster.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/cluster.js -->
+
 A single instance of Node.js runs in a single thread. To take advantage of
 multi-core systems, the user will sometimes want to launch a cluster of Node.js
 processes to handle the load.
diff --git a/doc/api/console.md b/doc/api/console.md
index 6d0b55a1eb0aee..db9b3955a56146 100644
--- a/doc/api/console.md
+++ b/doc/api/console.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/console.js -->
+
 The `console` module provides a simple debugging console that is similar to the
 JavaScript console mechanism provided by web browsers.
 
diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 2e1f2981ee7232..16c718090de6d3 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/crypto.js -->
+
 The `crypto` module provides cryptographic functionality that includes a set of
 wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions.
 
diff --git a/doc/api/dgram.md b/doc/api/dgram.md
index 05cab4e9b604b7..f13caa95525642 100644
--- a/doc/api/dgram.md
+++ b/doc/api/dgram.md
@@ -6,6 +6,8 @@
 
 <!-- name=dgram -->
 
+<!-- source_link=lib/dgram.js -->
+
 The `dgram` module provides an implementation of UDP datagram sockets.
 
 ```js
diff --git a/doc/api/dns.md b/doc/api/dns.md
index b02ee8b608d5bf..6268d22b22e5a4 100644
--- a/doc/api/dns.md
+++ b/doc/api/dns.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/dns.js -->
+
 The `dns` module enables name resolution. For example, use it to look up IP
 addresses of host names.
 
diff --git a/doc/api/domain.md b/doc/api/domain.md
index b9219fbb4d714e..109e41f749f1b4 100644
--- a/doc/api/domain.md
+++ b/doc/api/domain.md
@@ -16,6 +16,8 @@ changes:
 
 > Stability: 0 - Deprecated
 
+<!-- source_link=lib/domain.js -->
+
 **This module is pending deprecation**. Once a replacement API has been
 finalized, this module will be fully deprecated. Most end users should
 **not** have cause to use this module. Users who absolutely must have
diff --git a/doc/api/events.md b/doc/api/events.md
index 738e7e829753cc..d008b95641ea11 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -6,6 +6,8 @@
 
 <!--type=module-->
 
+<!-- source_link=lib/events.js -->
+
 Much of the Node.js core API is built around an idiomatic asynchronous
 event-driven architecture in which certain kinds of objects (called "emitters")
 emit named events that cause `Function` objects ("listeners") to be called.
diff --git a/doc/api/fs.md b/doc/api/fs.md
index a2dbdcc668b0f2..c64e44ab57c5e7 100644
--- a/doc/api/fs.md
+++ b/doc/api/fs.md
@@ -6,6 +6,8 @@
 
 <!--name=fs-->
 
+<!-- source_link=lib/fs.js -->
+
 The `fs` module provides an API for interacting with the file system in a
 manner closely modeled around standard POSIX functions.
 
diff --git a/doc/api/http.md b/doc/api/http.md
index 93390c9b35fa63..2069b2151be5fc 100644
--- a/doc/api/http.md
+++ b/doc/api/http.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/http.js -->
+
 To use the HTTP server and client one must `require('http')`.
 
 The HTTP interfaces in Node.js are designed to support many features
diff --git a/doc/api/http2.md b/doc/api/http2.md
index f4399cd91160fd..666d11d6de16c3 100644
--- a/doc/api/http2.md
+++ b/doc/api/http2.md
@@ -10,6 +10,8 @@ changes:
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/http2.js -->
+
 The `http2` module provides an implementation of the [HTTP/2][] protocol. It
 can be accessed using:
 
diff --git a/doc/api/https.md b/doc/api/https.md
index 197749592a265c..f94bf7f4e9e3da 100644
--- a/doc/api/https.md
+++ b/doc/api/https.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/https.js -->
+
 HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a
 separate module.
 
diff --git a/doc/api/inspector.md b/doc/api/inspector.md
index 4f9501a5f861a7..f541b9eb99fb68 100644
--- a/doc/api/inspector.md
+++ b/doc/api/inspector.md
@@ -4,6 +4,8 @@
 
 > Stability: 1 - Experimental
 
+<!-- source_link=lib/inspector.js -->
+
 The `inspector` module provides an API for interacting with the V8 inspector.
 
 It can be accessed using:
diff --git a/doc/api/net.md b/doc/api/net.md
index ae275b45d4d2bb..7baa8fa17017f7 100644
--- a/doc/api/net.md
+++ b/doc/api/net.md
@@ -5,6 +5,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/net.js -->
+
 The `net` module provides an asynchronous network API for creating stream-based
 TCP or [IPC][] servers ([`net.createServer()`][]) and clients
 ([`net.createConnection()`][]).
diff --git a/doc/api/os.md b/doc/api/os.md
index 807f0013c67700..8dd8a63fcfaa3e 100644
--- a/doc/api/os.md
+++ b/doc/api/os.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/os.js -->
+
 The `os` module provides operating system-related utility methods and
 properties. It can be accessed using:
 
diff --git a/doc/api/path.md b/doc/api/path.md
index 8349bce252a56b..14acbb1eb5f99d 100644
--- a/doc/api/path.md
+++ b/doc/api/path.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/path.js -->
+
 The `path` module provides utilities for working with file and directory paths.
 It can be accessed using:
 
diff --git a/doc/api/perf_hooks.md b/doc/api/perf_hooks.md
index c9d2d2e99ef474..392dc2a5245104 100644
--- a/doc/api/perf_hooks.md
+++ b/doc/api/perf_hooks.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/perf_hooks.js -->
+
 This module provides an implementation of a subset of the W3C
 [Web Performance APIs][] as well as additional APIs for
 Node.js-specific performance measurements.
diff --git a/doc/api/process.md b/doc/api/process.md
index de964f4f1e9341..8580a4eee6637b 100644
--- a/doc/api/process.md
+++ b/doc/api/process.md
@@ -3,6 +3,8 @@
 <!-- introduced_in=v0.10.0 -->
 <!-- type=global -->
 
+<!-- source_link=lib/process.js -->
+
 The `process` object is a `global` that provides information about, and control
 over, the current Node.js process. As a global, it is always available to
 Node.js applications without using `require()`. It can also be explicitly
diff --git a/doc/api/punycode.md b/doc/api/punycode.md
index 4c9dc3460a08dd..bcdfb9a167fd04 100644
--- a/doc/api/punycode.md
+++ b/doc/api/punycode.md
@@ -10,6 +10,8 @@ changes:
 
 > Stability: 0 - Deprecated
 
+<!-- source_link=lib/punycode.js -->
+
 **The version of the punycode module bundled in Node.js is being deprecated**.
 In a future major version of Node.js this module will be removed. Users
 currently depending on the `punycode` module should switch to using the
diff --git a/doc/api/querystring.md b/doc/api/querystring.md
index 0797e3ee220d53..03ee78aad0a23d 100644
--- a/doc/api/querystring.md
+++ b/doc/api/querystring.md
@@ -6,6 +6,8 @@
 
 <!--name=querystring-->
 
+<!-- source_link=lib/querystring.js -->
+
 The `querystring` module provides utilities for parsing and formatting URL
 query strings. It can be accessed using:
 
diff --git a/doc/api/readline.md b/doc/api/readline.md
index e20454a6cb399c..3b107afad7eb09 100644
--- a/doc/api/readline.md
+++ b/doc/api/readline.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/readline.js -->
+
 The `readline` module provides an interface for reading data from a [Readable][]
 stream (such as [`process.stdin`][]) one line at a time. It can be accessed
 using:
diff --git a/doc/api/repl.md b/doc/api/repl.md
index 614c577d2cfd44..bf0727e47719ca 100644
--- a/doc/api/repl.md
+++ b/doc/api/repl.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/repl.js -->
+
 The `repl` module provides a Read-Eval-Print-Loop (REPL) implementation that
 is available both as a standalone program or includible in other applications.
 It can be accessed using:
diff --git a/doc/api/stream.md b/doc/api/stream.md
index b195458cec9b4f..f2e30a910302b1 100644
--- a/doc/api/stream.md
+++ b/doc/api/stream.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/stream.js -->
+
 A stream is an abstract interface for working with streaming data in Node.js.
 The `stream` module provides an API for implementing the stream interface.
 
diff --git a/doc/api/string_decoder.md b/doc/api/string_decoder.md
index 5cd6121d50ddb9..59056b861321b4 100644
--- a/doc/api/string_decoder.md
+++ b/doc/api/string_decoder.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/string_decoder.js -->
+
 The `string_decoder` module provides an API for decoding `Buffer` objects into
 strings in a manner that preserves encoded multi-byte UTF-8 and UTF-16
 characters. It can be accessed using:
diff --git a/doc/api/timers.md b/doc/api/timers.md
index cb26e4b16a3bae..fb9c765dc4558a 100644
--- a/doc/api/timers.md
+++ b/doc/api/timers.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/timers.js -->
+
 The `timer` module exposes a global API for scheduling functions to
 be called at some future period of time. Because the timer functions are
 globals, there is no need to call `require('timers')` to use the API.
diff --git a/doc/api/tls.md b/doc/api/tls.md
index 9b06fde493e6a2..8e6c0d4da1615a 100644
--- a/doc/api/tls.md
+++ b/doc/api/tls.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/tls.js -->
+
 The `tls` module provides an implementation of the Transport Layer Security
 (TLS) and Secure Socket Layer (SSL) protocols that is built on top of OpenSSL.
 The module can be accessed using:
diff --git a/doc/api/tracing.md b/doc/api/tracing.md
index 907fc2bbe23ba7..9350e0b9ca97da 100644
--- a/doc/api/tracing.md
+++ b/doc/api/tracing.md
@@ -4,6 +4,8 @@
 
 > Stability: 1 - Experimental
 
+<!-- source_link=lib/trace_events.js -->
+
 The `trace_events` module provides a mechanism to centralize tracing information
 generated by V8, Node.js core, and userspace code.
 
diff --git a/doc/api/tty.md b/doc/api/tty.md
index b1b1ebdb26796a..f4a83c290a3854 100644
--- a/doc/api/tty.md
+++ b/doc/api/tty.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/tty.js -->
+
 The `tty` module provides the `tty.ReadStream` and `tty.WriteStream` classes.
 In most cases, it will not be necessary or possible to use this module directly.
 However, it can be accessed using:
diff --git a/doc/api/url.md b/doc/api/url.md
index d2d512a17d8ded..7d493026fd46ea 100644
--- a/doc/api/url.md
+++ b/doc/api/url.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/url.js -->
+
 The `url` module provides utilities for URL resolution and parsing. It can be
 accessed using:
 
diff --git a/doc/api/util.md b/doc/api/util.md
index 4aeec0ba9c6110..27f3bd50ed743a 100644
--- a/doc/api/util.md
+++ b/doc/api/util.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/util.js -->
+
 The `util` module supports the needs of Node.js internal APIs. Many of the
 utilities are useful for application and module developers as well. To access
 it:
diff --git a/doc/api/v8.md b/doc/api/v8.md
index 531612330f061b..921c4378199496 100644
--- a/doc/api/v8.md
+++ b/doc/api/v8.md
@@ -2,6 +2,8 @@
 
 <!--introduced_in=v4.0.0-->
 
+<!-- source_link=lib/v8.js -->
+
 The `v8` module exposes APIs that are specific to the version of [V8][]
 built into the Node.js binary. It can be accessed using:
 
diff --git a/doc/api/vm.md b/doc/api/vm.md
index f5fcd7d8bfb1ab..62a1075eb68315 100644
--- a/doc/api/vm.md
+++ b/doc/api/vm.md
@@ -6,6 +6,8 @@
 
 <!--name=vm-->
 
+<!-- source_link=lib/vm.js -->
+
 The `vm` module enables compiling and running code within V8 Virtual
 Machine contexts. **The `vm` module is not a security mechanism. Do
 not use it to run untrusted code**.
diff --git a/doc/api/wasi.md b/doc/api/wasi.md
index b46aacfbcb1ecb..46673af9e7fb34 100644
--- a/doc/api/wasi.md
+++ b/doc/api/wasi.md
@@ -4,6 +4,8 @@
 
 > Stability: 1 - Experimental
 
+<!-- source_link=lib/wasi.js -->
+
 The WASI API provides an implementation of the [WebAssembly System Interface][]
 specification. WASI gives sandboxed WebAssembly applications access to the
 underlying operating system via a collection of POSIX-like functions.
diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md
index 67823a527509fb..8cd4925b632e6a 100644
--- a/doc/api/worker_threads.md
+++ b/doc/api/worker_threads.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/worker_threads.js -->
+
 The `worker_threads` module enables the use of threads that execute JavaScript
 in parallel. To access it:
 
diff --git a/doc/api/zlib.md b/doc/api/zlib.md
index d333b99b75d6eb..a64ae57c7bc233 100644
--- a/doc/api/zlib.md
+++ b/doc/api/zlib.md
@@ -4,6 +4,8 @@
 
 > Stability: 2 - Stable
 
+<!-- source_link=lib/zlib.js -->
+
 The `zlib` module provides compression functionality implemented using Gzip,
 Deflate/Inflate, and Brotli.
 
diff --git a/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js
index 0ffa9f9149085d..30221a7fe18b1a 100644
--- a/test/doctool/test-doctool-html.js
+++ b/test/doctool/test-doctool-html.js
@@ -41,7 +41,7 @@ function toHTML({ input, filename, nodeVersion, versions }) {
     .use(replaceLinks, { filename, linksMapper: testLinksMapper })
     .use(markdown)
     .use(html.firstHeader)
-    .use(html.preprocessText)
+    .use(html.preprocessText, { nodeVersion })
     .use(html.preprocessElements, { filename })
     .use(html.buildToc, { filename, apilinks: {} })
     .use(remark2rehype, { allowDangerousHTML: true })
diff --git a/tools/doc/common.js b/tools/doc/common.js
index 86daae6cfc6d56..11e4ad6e2c99aa 100644
--- a/tools/doc/common.js
+++ b/tools/doc/common.js
@@ -7,6 +7,10 @@ function isYAMLBlock(text) {
   return /^<!-- YAML/.test(text);
 }
 
+function isSourceLink(text) {
+  return /^<!-- source_link=([^\s/]+\/)+\w+\.\w+ -->/.test(text);
+}
+
 function arrify(value) {
   return Array.isArray(value) ? value : [value];
 }
@@ -43,4 +47,4 @@ function extractAndParseYAML(text) {
   return meta;
 }
 
-module.exports = { arrify, isYAMLBlock, extractAndParseYAML };
+module.exports = { arrify, isYAMLBlock, isSourceLink, extractAndParseYAML };
diff --git a/tools/doc/generate.js b/tools/doc/generate.js
index dcb72a99d931f6..93c3b263009bb6 100644
--- a/tools/doc/generate.js
+++ b/tools/doc/generate.js
@@ -82,7 +82,7 @@ async function main() {
   const content = await unified()
     .use(replaceLinks, { filename, linksMapper })
     .use(markdown)
-    .use(html.preprocessText)
+    .use(html.preprocessText, { nodeVersion })
     .use(json.jsonAPI, { filename })
     .use(html.firstHeader)
     .use(html.preprocessElements, { filename })
diff --git a/tools/doc/html.js b/tools/doc/html.js
index b58563045def8d..b8333f8bcbc498 100644
--- a/tools/doc/html.js
+++ b/tools/doc/html.js
@@ -104,10 +104,13 @@ function firstHeader() {
 
 // Handle general body-text replacements.
 // For example, link man page references to the actual page.
-function preprocessText() {
+function preprocessText({ nodeVersion }) {
   return (tree) => {
     visit(tree, null, (node) => {
-      if (node.type === 'text' && node.value) {
+      if (common.isSourceLink(node.value)) {
+        const [path] = node.value.match(/(?<=<!-- source_link=).*(?= -->)/);
+        node.value = `<p><strong>Source Code:</strong> <a href="https://github.com/nodejs/node/blob/${nodeVersion}/${path}">${path}</a></p>`;
+      } else if (node.type === 'text' && node.value) {
         const value = linkJsTypeDocs(linkManPages(node.value));
         if (value !== node.value) {
           node.type = 'html';