Skip to content

Overview

The experimental namespace is a Tier-4 override surface for behaviour changes not covered by before* events, static replaces, or subclass hooks. It lets consumers and plugins monkey-patch player methods at runtime without touching the prototype.

Use this as a last resort. Before reaching for experimental.override, check whether a before* event listener or a plugin advisory solves the problem.

player.experimental.override(method, fn)

Temporarily replace a player method with a custom implementation.

The original method is captured on first call. Multiple overrides of the same method overwrite each other, the last writer wins. Returns a zero-arg disposer; call it to undo the override.

ParameterTypeDescription
methodstringName of the method to override
fn(...args: unknown[]) => unknownReplacement function (called with the player as this)

Returns: () => void, call to restore the original

TypeScript
const restore = player.experimental.override('play', async function (...args) {
// custom logic before play
console.log('play intercepted');

// call through to the original
const entry = player.experimental.overrides().find((override) => override.method === 'play');

// NOTE: to call-through you'd need to capture the original before overriding
// This is intentionally low-level, use beforePlay event instead when possible
});

// later, when done
restore();

player.experimental.restore(method)

Remove the active override for method and restore the original implementation. No-op when the method has no active override.

TypeScript
player.experimental.restore('play');

player.experimental.overrides()

Snapshot of all active overrides. by is always 'consumer'override() is a consumer-only API (plugin code is lint-blocked from calling it), so it records 'consumer' regardless of caller.

Returns: Array<{ method: string; by: 'consumer' }>

TypeScript
const active = player.experimental.overrides();
// e.g. [{ method: 'play', by: 'consumer' }, { method: 'time', by: 'consumer' }]

Plugin lint rule

The ESLint rule nmplayer/no-experimental flags any call to experimental.override from inside plugin code. Plugin authors must add an ESLint disable comment with a written reason:

TypeScript
// eslint-disable-next-line nmplayer/no-experimental
player.experimental.override('play', myFn);

Consumer (app) code is free to use it without lint friction.

Restoring an override

override() returns a restore function — call it to undo that one override. There is no automatic restore: overrides persist until you call the returned function, and removePlugin does not touch them.

See also