mrkeyoor.com_
Sat 08 Aug 22:51 UTC
npmWeb Frontendupdated 08 Aug 2026

custom-event

custom-event is a tiny CommonJS compatibility constructor for DOM CustomEvent objects. It exports the browser's native constructor when a quick feature test succeeds, otherwise it falls back to document.createEvent and initCustomEvent for IE 9 and newer, with a separate createEventObject path for IE 8. It carries a value in event.detail, but it is not an event bus, listener registry, Node EventEmitter, or full DOM shim.

Verdict

Keep custom-event when an old browser bundle already depends on its IE fallbacks. For a new application targeting current browsers, the native constructor is the clearer choice and costs no dependency.

API stability5/5The public surface is one constructor with the standard CustomEvent arguments, and version 1.0.1 has stayed unchanged since October 2016. The source chooses between native and legacy implementations without adding package-specific methods, so there is almost nothing to relearn or accidentally break. That stability comes partly from inactivity, but callers that only construct type, detail, bubbles, and cancelable values face a very small compatibility surface.
Docs2/5The README explains installation and gives one correct listener, detail, construction, and dispatch example, then links to MDN for the platform API. It does not document Node and worker behavior, CommonJS bundling expectations, the IE 8 event-like object limitations, TypeScript, or which browsers still need the fallback. Open issues #4, #5, and #6 expose important environment and legacy-support questions that a user must answer from source rather than documentation.
Maintenance1/5The repository is not archived and npm does not mark the package deprecated, but its last push and latest release were both in October 2016. Three open issues remain, including requests for a Node version, no-global fallback, and a build without IE 8 support. A tiny compatibility shim may be functionally complete, yet there is no recent release, test modernization, security response evidence, or visible work adapting the package to current module and typing conventions.
Ecosystem3/5The package recorded 3,625,102 downloads for the measured week, which shows that it remains deeply embedded in dependency trees. Its API matches the browser standard and therefore works with normal addEventListener and dispatchEvent calls. On the other hand, the repository has 99 stars, publishes only CommonJS, includes no declarations, and offers no plugin ecosystem because it is a single-purpose constructor rather than a framework developers intentionally extend.

Use it if

  • You maintain a browser bundle that must still create CustomEvent objects on Internet Explorer
  • A transitive dependency already expects require('custom-event') and replacing that call would add needless churn
  • You need one CommonJS import that uses the native constructor when it works and falls back when it does not
  • You are repairing an older application whose build and test matrix already includes this exact package
Skip it if

Setup reality

Installation is only npm install custom-event, and runtime version 1.0.1 has no dependencies or peer dependencies. The import is CommonJS: var CustomEvent = require('custom-event'). In an older browser bundle, Browserify, webpack, or another CommonJS-aware build step must turn that require into browser code; the package does not publish an ESM entry, browser field, TypeScript declaration, or ready-to-copy minified browser file. Its startup feature test reads global.CustomEvent and tries to construct an event. If that fails, it selects a document-based fallback. That is useful in IE, but it does not create a document for Node, workers, or server rendering. In an environment with neither a usable native CustomEvent nor document, construction reaches document.createEventObject and throws. Importing can still appear safe because document is read inside the fallback function, so the surprise may wait until the first new CustomEvent call. The IE 9 path maps params.bubbles, params.cancelable, and params.detail into initCustomEvent; omitted options become false, false, and undefined. The IE 8 branch only creates an event-like object, so do not assume every modern Event method or propagation behavior is present. There is no configuration file, build hook, native compilation, credential, or production service to set up. The real setup decision is whether your supported browser list still contains the legacy engines this seven-line public API exists to cover. If it does not, use globalThis.CustomEvent directly and remove the dependency.

Patterns

Install the constructorinstall-package

npm install custom-event

Version 1.0.1 has no runtime or peer dependencies, but the published entry point is CommonJS.

Import from CommonJSimport-constructor

var CustomEvent = require('custom-event');

There is no ESM export or TypeScript declaration in the package metadata.

Dispatch structured detaildispatch-detail

var CustomEvent = require('custom-event');

var event = new CustomEvent('cart:add', {
  detail: { sku: 'A-42', quantity: 2 }
});
document.dispatchEvent(event);

The payload belongs in detail; adding arbitrary top-level properties is not the CustomEvent API.

Read detail in a listenerlisten-for-event

document.addEventListener('cart:add', function (event) {
  console.log(event.detail.sku, event.detail.quantity);
});

Register the listener on the same target, or an ancestor when the custom event is configured to bubble.

Create a bubbling eventenable-bubbling

var event = new CustomEvent('menu:select', {
  bubbles: true,
  detail: { value: 'settings' }
});
button.dispatchEvent(event);

bubbles defaults to false in both fallback branches, so delegation requires setting it explicitly.

Create a cancelable eventmake-cancelable

var event = new CustomEvent('dialog:before-close', {
  cancelable: true,
  detail: { reason: 'escape' }
});

var accepted = dialog.dispatchEvent(event);
if (!accepted) console.log('close was canceled');

A listener must call preventDefault, and cancelable must be true, for dispatchEvent to return false.

Cancel a proposed actioncancel-in-listener

dialog.addEventListener('dialog:before-close', function (event) {
  if (hasUnsavedChanges()) event.preventDefault();
});

Do not depend on modern Event methods in the package's IE 8 createEventObject branch without testing that browser path.

Delegate a bubbling custom eventdelegate-event

list.addEventListener('row:activate', function (event) {
  console.log('activated', event.detail.id);
});

row.dispatchEvent(new CustomEvent('row:activate', {
  bubbles: true,
  detail: { id: 17 }
}));

The event only reaches list when row is a descendant and bubbles is enabled.

Dispatch from a specific elementdispatch-from-element

var input = document.querySelector('#search');
input.dispatchEvent(new CustomEvent('search:clear', {
  detail: { previousValue: input.value }
}));

The package constructs the event only; dispatchEvent is supplied by the DOM target.

Construct an event without optionsomit-options

var ready = new CustomEvent('widget:ready');
widget.dispatchEvent(ready);

The fallbacks set bubbles and cancelable to false and detail to undefined when params is omitted.

Pass the event to platform codebridge-native-code

function announce(target, name, data) {
  target.dispatchEvent(new CustomEvent(name, { detail: data }));
}

announce(window, 'session:expired', { at: Date.now() });

The export is the native constructor when its startup feature test succeeds, so consumers use the normal DOM event contract.

Avoid construction during server renderingguard-server-rendering

if (typeof document !== 'undefined') {
  var CustomEvent = require('custom-event');
  document.dispatchEvent(new CustomEvent('app:hydrated'));
}

When no usable native global exists, construction needs document; the package does not provide a server-side DOM.

Alternatives

PackageRegistryPick it when
custom-event-polyfillnpmChoose it when you want a side-effect polyfill for IE 9 and newer instead of changing every constructor import
event-target-shimnpmChoose it when the missing piece is a WHATWG-style EventTarget implementation, not just CustomEvent construction
eventemitter3npmChoose it for application-level events across Node and browsers where DOM propagation semantics are unnecessary