diff --git a/.eslintrc.js b/.eslintrc.js
index 8464945125b678..99f7196ffc8158 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -287,6 +287,11 @@ module.exports = {
BigInt: 'readable',
BigInt64Array: 'readable',
BigUint64Array: 'readable',
+ Event: 'readable',
+ EventTarget: 'readable',
+ MessageChannel: 'readable',
+ MessageEvent: 'readable',
+ MessagePort: 'readable',
TextEncoder: 'readable',
TextDecoder: 'readable',
queueMicrotask: 'readable',
diff --git a/doc/api/events.md b/doc/api/events.md
index 5de7e06840ef5e..11e13e6d852ea6 100644
--- a/doc/api/events.md
+++ b/doc/api/events.md
@@ -1069,9 +1069,15 @@ const ac = new AbortController();
process.nextTick(() => ac.abort());
```
+
## `EventTarget` and `Event` API
> Stability: 1 - Experimental
@@ -1082,7 +1088,7 @@ Neither the `EventTarget` nor `Event` classes are available for end
user code to create.
```js
-const target = getEventTargetSomehow();
+const target = new EventTarget();
target.addEventListener('foo', (event) => {
console.log('foo event happened!');
@@ -1168,7 +1174,7 @@ const handler4 = {
}
};
-const target = getEventTargetSomehow();
+const target = new EventTarget();
target.addEventListener('foo', handler1);
target.addEventListener('foo', handler2);
@@ -1189,6 +1195,10 @@ The `EventTarget` does not implement any special default handling for
### Class: `Event`
The `Event` object is an adaptation of the [`Event` Web API][]. Instances
@@ -1341,6 +1351,11 @@ The event type identifier.
### Class: `EventTarget`
#### `eventTarget.addEventListener(type, listener[, options])`
@@ -1374,7 +1389,7 @@ a `listener`. Any individual `listener` may be added once with
```js
function handler(event) {}
-const target = getEventTargetSomehow();
+const target = new EventTarget();
target.addEventListener('foo', handler, { capture: true }); // first
target.addEventListener('foo', handler, { capture: false }); // second
diff --git a/doc/api/globals.md b/doc/api/globals.md
index 8b279a21715e6b..4191c1e017afc7 100644
--- a/doc/api/globals.md
+++ b/doc/api/globals.md
@@ -169,6 +169,30 @@ added: v0.1.100
Used to print to stdout and stderr. See the [`console`][] section.
+## `Event`
+
+
+
+
+> Stability: 1 - Experimental
+
+A browser-compatible implementation of the `Event` class. See
+[`EventTarget` and `Event` API][] for more details.
+
+## `EventTarget`
+
+
+
+
+> Stability: 1 - Experimental
+
+A browser-compatible implementation of the `EventTarget` class. See
+[`EventTarget` and `Event` API][] for more details.
+
## `exports`
This variable may appear to be global but is not. See [`exports`][].
@@ -187,6 +211,33 @@ within the browser `var something` will define a new global variable. In
Node.js this is different. The top-level scope is not the global scope;
`var something` inside a Node.js module will be local to that module.
+## `MessageChannel`
+
+
+
+
+The `MessageChannel` class. See [`MessageChannel`][] for more details.
+
+## `MessageEvent`
+
+
+
+
+The `MessageEvent` class. See [`MessageEvent`][] for more details.
+
+## `MessagePort`
+
+
+
+
+The `MessagePort` class. See [`MessagePort`][] for more details.
+
## `module`
This variable may appear to be global but is not. See [`module`][].
@@ -322,6 +373,10 @@ The object that acts as the namespace for all W3C
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
+[`EventTarget` and `Event` API]: events.md#event-target-and-event-api
+[`MessageChannel`]: worker_threads.md#worker_threads_class_messagechannel
+[`MessageEvent`]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
+[`MessagePort`]: worker_threads.md#worker_threads_class_messageport
[`TextDecoder`]: util.md#util_class_util_textdecoder
[`TextEncoder`]: util.md#util_class_util_textencoder
[`URLSearchParams`]: url.md#url_class_urlsearchparams
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index 551367583e55a8..bb4689d0d342e8 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -140,6 +140,21 @@ if (!config.noBrowserGlobals) {
exposeInterface(global, 'AbortController', AbortController);
exposeInterface(global, 'AbortSignal', AbortSignal);
+ const {
+ EventTarget,
+ Event,
+ } = require('internal/event_target');
+ exposeInterface(global, 'EventTarget', EventTarget);
+ exposeInterface(global, 'Event', Event);
+ const {
+ MessageChannel,
+ MessagePort,
+ MessageEvent,
+ } = require('internal/worker/io');
+ exposeInterface(global, 'MessageChannel', MessageChannel);
+ exposeInterface(global, 'MessagePort', MessagePort);
+ exposeInterface(global, 'MessageEvent', MessageEvent);
+
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
const timers = require('timers');
defineOperation(global, 'clearInterval', timers.clearInterval);
diff --git a/src/node_external_reference.h b/src/node_external_reference.h
index f332103c3f5a27..0544979dd9a6f1 100644
--- a/src/node_external_reference.h
+++ b/src/node_external_reference.h
@@ -64,7 +64,8 @@ class ExternalReferenceRegistry {
V(string_decoder) \
V(trace_events) \
V(timers) \
- V(types)
+ V(types) \
+ V(worker)
#if NODE_HAVE_I18N_SUPPORT
#define EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) V(icu)
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 4159a6efeda780..cdaeefb7897794 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -2,6 +2,7 @@
#include "debug_utils-inl.h"
#include "memory_tracker-inl.h"
#include "node_errors.h"
+#include "node_external_reference.h"
#include "node_buffer.h"
#include "node_options-inl.h"
#include "node_perf.h"
@@ -860,9 +861,20 @@ void InitWorker(Local