diff --git a/src/content/changelogs-next/2025-01-28-nodejs-compat-improvements.mdx b/src/content/changelogs-next/2025-01-28-nodejs-compat-improvements.mdx
new file mode 100644
index 00000000000000..7b9bc9595c70a1
--- /dev/null
+++ b/src/content/changelogs-next/2025-01-28-nodejs-compat-improvements.mdx
@@ -0,0 +1,91 @@
+---
+title: Support for Node.js DNS, Net, and Timer APIs in Workers
+description: Node.js APIs from the node:dns, node:net, and node:timers modules are now available when using nodejs_compat.
+products:
+ - workers
+date: 2025-01-28T13:00:00Z
+---
+
+import { Render, PackageManagers, TypeScriptExample } from "~/components";
+
+When using a Worker with the [`nodejs_compat`](/workers/runtime-apis/nodejs/) compatibility flag enabled, you can now use the following Node.js APIs:
+
+- [`node:net`](/workers/runtime-apis/nodejs/net/)
+- [`node:dns`](/workers/runtime-apis/nodejs/dns/)
+- [`node:timers`](/workers/runtime-apis/nodejs/timers/)
+
+#### node:net
+
+This makes it possible to connect to databases such as [MySQL](https://www.mysql.com/), [PostgreSQL](https://www.postgresql.org/),
+[Redis](https://redis.io/), or [MongoDB](https://github.com/mongodb/mongo). Though for production use, we recommend that you connect
+using TLS, which can be done with the [`cloudflare:sockets`](/workers/runtime-apis/tcp-sockets/#connect)
+module, or prefereably by using [Hyperdrive](/hyperdrive), which includes
+[connection pooling](/hyperdrive/configuration/how-hyperdrive-works/#connection-pooling)
+and [query caching](/hyperdrive/configuration/how-hyperdrive-works/#query-caching).
+
+
+```ts
+import net from "node:net";
+
+const exampleIP = "127.0.0.1";
+
+export default {
+ async fetch(req): Promise {
+ const socket = new net.Socket();
+ socket.connect(4000, exampleIP, function () {
+ console.log("Connected");
+ });
+
+ socket.write("Hello, Server!");
+ socket.end();
+
+ return new Response("Wrote to server", { status: 200 });
+ },
+} satisfies ExportedHandler;
+````
+
+
+Additionally, you can now use other APIs incliding [`net.BlockList`](https://nodejs.org/api/net.html#class-netblocklist) and
+[`net.SocketAddress`](https://nodejs.org/api/net.html#class-netsocketaddress).
+
+Note that [`net.Server`](https://nodejs.org/api/net.html#class-netserver) is not supported.
+
+#### node:dns
+
+You can use [`node:dns`](https://nodejs.org/api/dns.html) for name resolution via [DNS over HTTPS](/1.1.1.1/encryption/dns-over-https/) using
+[Cloudflare DNS](https://www.cloudflare.com/application-services/products/dns/) at 1.1.1.1.
+
+
+```ts
+import dns from "node:dns";
+
+dns.lookup("example.org", (_err: any, address: string, ipFamily: number) =>
+ console.log(`address: ${address} family: IPv${ipFamily}`));
+````
+
+
+
+All `node:dns` functions are available, except `lookup`, `lookupService`, and `resolve` which throw "Not implemented" errors when called.
+
+#### node:timers
+
+You can use [`node:timers`](https://nodejs.org/api/timers.html) to schedule functions to be called at some future period of time.
+
+This includes [`setTimeout`](https://nodejs.org/api/timers.html#settimeoutcallback-delay-args) for calling a function after a delay,
+[`setInterval`](https://nodejs.org/api/timers.html#setintervalcallback-delay-args) for calling a function repeatedly,
+and [`setImmediate`](https://nodejs.org/api/timers.html#setimmediatecallback-args) for calling a function in the next iteration of the event loop.
+
+
+```ts
+import timers from "node:timers";
+
+console.log("first");
+timers.setTimeout(() => {
+ console.log("last");
+}, 10);
+
+timers.setTimeout(() => {
+ console.log("next");
+});
+```
+
diff --git a/src/content/docs/workers/runtime-apis/nodejs/assert.mdx b/src/content/docs/workers/runtime-apis/nodejs/assert.mdx
index 2f2fd14973dca0..27073dff3bdb86 100644
--- a/src/content/docs/workers/runtime-apis/nodejs/assert.mdx
+++ b/src/content/docs/workers/runtime-apis/nodejs/assert.mdx
@@ -1,39 +1,35 @@
---
pcx_content_type: configuration
title: assert
-
---
-import { Render } from "~/components"
+import { Render } from "~/components";
The `assert` module in Node.js provides a number of useful assertions that are useful when building tests.
```js
-import {
- strictEqual,
- deepStrictEqual,
- ok,
- doesNotReject,
-} from 'node:assert';
+import { strictEqual, deepStrictEqual, ok, doesNotReject } from "node:assert";
strictEqual(1, 1); // ok!
strictEqual(1, "1"); // fails! throws AssertionError
-deepStrictEqual({ a: { b: 1 }}, { a: { b: 1 }});// ok!
-deepStrictEqual({ a: { b: 1 }}, { a: { b: 2 }});// fails! throws AssertionError
+deepStrictEqual({ a: { b: 1 } }, { a: { b: 1 } }); // ok!
+deepStrictEqual({ a: { b: 1 } }, { a: { b: 2 } }); // fails! throws AssertionError
ok(true); // ok!
ok(false); // fails! throws AssertionError
await doesNotReject(async () => {}); // ok!
-await doesNotReject(async () => { throw new Error('boom') }); // fails! throws AssertionError
+await doesNotReject(async () => {
+ throw new Error("boom");
+}); // fails! throws AssertionError
```
:::note
-In the Workers implementation of `assert`, all assertions run in, what Node.js calls, the strict assertion mode. In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example, `deepEqual()` will behave like `deepStrictEqual()`.
+In the Workers implementation of `assert`, all assertions run in, what Node.js calls, the strict assertion mode. In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example, `deepEqual()` will behave like `deepStrictEqual()`.
:::
Refer to the [Node.js documentation for `assert`](https://nodejs.org/dist/latest-v19.x/docs/api/assert.html) for more information.
diff --git a/src/content/docs/workers/runtime-apis/nodejs/dns.mdx b/src/content/docs/workers/runtime-apis/nodejs/dns.mdx
new file mode 100644
index 00000000000000..53b18f69aa3e88
--- /dev/null
+++ b/src/content/docs/workers/runtime-apis/nodejs/dns.mdx
@@ -0,0 +1,28 @@
+---
+pcx_content_type: configuration
+title: dns
+---
+
+import { Render, TypeScriptExample } from "~/components";
+
+
+
+You can use [`node:dns`](https://nodejs.org/api/dns.html) for name resolution via [DNS over HTTPS](/1.1.1.1/encryption/dns-over-https/) using
+[Cloudflare DNS](https://www.cloudflare.com/application-services/products/dns/) at 1.1.1.1.
+
+
+```ts
+import dns from "node:dns";
+
+dns.lookup("example.org", (_err: any, address: string, ipFamily: number) =>
+ console.log(`address: ${address} family: IPv${ipFamily}`));
+```
+
+
+:::note
+
+DNS requests will execute a subrequest, counts for your [Worker's subrequest limit](/workers/platform/limits/#subrequests).
+
+:::
+
+The full `node:dns` API is documented in the [Node.js documentation for `node:dns`](https://nodejs.org/api/dns.html).
diff --git a/src/content/docs/workers/runtime-apis/nodejs/net.mdx b/src/content/docs/workers/runtime-apis/nodejs/net.mdx
new file mode 100644
index 00000000000000..f25af8183c10cc
--- /dev/null
+++ b/src/content/docs/workers/runtime-apis/nodejs/net.mdx
@@ -0,0 +1,50 @@
+---
+pcx_content_type: configuration
+title: net
+---
+
+import { Render, TypeScriptExample } from "~/components";
+
+
+
+You can use [`node:net`](https://nodejs.org/api/net.html) to create a direct connection to servers via a TCP sockets
+with [`net.Socket`](https://nodejs.org/api/net.html#class-netsocket).
+
+This makes it possible to connect to databases such as [MySQL](https://www.mysql.com/), [PostgreSQL](https://www.postgresql.org/),
+[Redis](https://redis.io/), or [MongoDB](https://github.com/mongodb/mongo). Though for production use, we recommend that you connect
+using TLS, which can be done with the [`cloudflare:sockets`](/workers/runtime-apis/tcp-sockets/#connect)
+module, or prefereably by using [Hyperdrive](/hyperdrive), which includes
+[connection pooling](/hyperdrive/configuration/how-hyperdrive-works/#connection-pooling)
+and [query caching](/hyperdrive/configuration/how-hyperdrive-works/#query-caching).
+
+These functions use [`connect`](/workers/runtime-apis/tcp-sockets/#connect) functionality from the built-in `cloudflare:sockets` module.
+
+
+```ts
+import net from "node:net";
+
+const exampleIP = "127.0.0.1";
+
+export default {
+ async fetch(req): Promise {
+ const socket = new net.Socket();
+ socket.connect(4000, exampleIP, function () {
+ console.log("Connected");
+ });
+
+ socket.write("Hello, Server!");
+ socket.end();
+
+ return new Response("Wrote to server", { status: 200 });
+ },
+} satisfies ExportedHandler;
+
+```
+
+
+Additionally, other APIs such as [`net.BlockList`](https://nodejs.org/api/net.html#class-netblocklist)
+and [`net.SocketAddress`](https://nodejs.org/api/net.html#class-netsocketaddress) are available.
+
+Note that the [`net.Server`](https://nodejs.org/api/net.html#class-netserver) class is not supported by Workers.
+
+The full `node:net` API is documented in the [Node.js documentation for `node:net`](https://nodejs.org/api/net.html).
diff --git a/src/content/docs/workers/runtime-apis/nodejs/path.mdx b/src/content/docs/workers/runtime-apis/nodejs/path.mdx
index a1c0f4a6030236..259940aed82c90 100644
--- a/src/content/docs/workers/runtime-apis/nodejs/path.mdx
+++ b/src/content/docs/workers/runtime-apis/nodejs/path.mdx
@@ -1,24 +1,18 @@
---
pcx_content_type: configuration
title: path
-
---
-import { Render } from "~/components"
+import { Render } from "~/components";
The [`node:path`](https://nodejs.org/api/path.html) module provides utilities for working with file and directory paths. The `node:path` module can be accessed using:
```js
-import path from "node:path"
-path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
+import path from "node:path";
+path.join("/foo", "bar", "baz/asdf", "quux", "..");
// Returns: '/foo/bar/baz/asdf'
```
-:::note
-
-In the Workers implementation of `path`, the [path.win32](https://nodejs.org/api/path.html#windows-vs-posix) variants of the path API are not implemented, and will throw an exception.
-:::
-
Refer to the [Node.js documentation for `path`](https://nodejs.org/api/path.html) for more information.
diff --git a/src/content/docs/workers/runtime-apis/nodejs/timers.mdx b/src/content/docs/workers/runtime-apis/nodejs/timers.mdx
new file mode 100644
index 00000000000000..6fddbfb4c456dc
--- /dev/null
+++ b/src/content/docs/workers/runtime-apis/nodejs/timers.mdx
@@ -0,0 +1,43 @@
+---
+pcx_content_type: configuration
+title: timers
+---
+
+import { Render, TypeScriptExample } from "~/components";
+
+
+
+Use [`node:timers`](https://nodejs.org/api/timers.html) APIs to schedule functions to be executed later.
+
+This includes [`setTimeout`](https://nodejs.org/api/timers.html#settimeoutcallback-delay-args) for calling a function after a delay,
+[`setInterval`](https://nodejs.org/api/timers.html#clearintervaltimeout) for calling a function repeatedly,
+and [`setImmediate`](https://nodejs.org/api/timers.html#setimmediatecallback-args) for calling a function in the next iteration of the event loop.
+
+
+```ts
+import timers from "node:timers";
+
+console.log("first");
+timers.setTimeout(() => {
+ console.log("last");
+}, 10);
+
+timers.setTimeout(() => {
+ console.log("next");
+});
+```
+
+
+:::note
+Due to [security-based restrictions on timers](/workers/reference/security-model/#step-1-disallow-timers-and-multi-threading) in Workers,
+timers are limited to returning the time of the last I/O. This means that while setTimeout, setInterval, and setImmediate will defer your function execution
+until after other events have run, they will not delay them for the full time specified.
+:::
+
+:::note
+When called from a global level (on [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis)),
+functions such as `clearTimeout` and `setTimeout` will respect web standards rather than Node.js-specific functionality. For complete Node.js
+compatibility, you must call functions from the `node:timers` module.
+:::
+
+The full `node:timers` API is documented in the [Node.js documentation for `node:timers`](https://nodejs.org/api/timers.html).