Migration Guide

Migration Guide

v0 → v1

nipplejs v1 includes several breaking changes to improve naming consistency and simplify the API. This guide covers every breaking change with before/after code comparisons.

maxNumberOfNipplesmaxNumberOfJoysticks

The option was renamed to align with the updated terminology.

Before (v0)

const manager = nipplejs.create({
    maxNumberOfNipples: 5,
});

After (v1)

const manager = nipplejs.create({
    maxNumberOfJoysticks: 5,
});

destroyed event → joystickDestroyed

The event name was made more specific to avoid ambiguity with collection and factory destruction events.

Before (v0)

manager.on('destroyed', (evt, data) => {
    console.log('A joystick was destroyed');
});

After (v1)

manager.on('joystickDestroyed', (evt) => {
    console.log('A joystick was destroyed');
});

joystick.eljoystick.ui.el

DOM element references are now grouped under the ui property, alongside ui.front (thumb) and ui.back (outer circle).

Before (v0)

manager.on('added', (evt, joystick) => {
    joystick.el.style.background = 'red';
});

After (v1)

manager.on('added', (evt) => {
    evt.data.ui.el.style.background = 'red';
});

show(), hide(), add(), remove() methods removed

These methods have been removed. Joystick visibility and lifecycle are now managed entirely through the mode system (dynamic, semi, static) and the destroy() method.

Before (v0)

joystick.show();
joystick.hide();
manager.add();
manager.remove();

After (v1)

// Visibility is controlled by mode and fade transitions.
// To remove a joystick, destroy it:
joystick.destroy();

// To remove all joysticks, destroy the collection:
manager.destroy();

manager.get(id)manager.getJoystickByUid(uid)

The lookup method was renamed for clarity. You can also iterate the all map directly.

Before (v0)

const joystick = manager.get(0);

After (v1)

const joystick = manager.getJoystickByUid(0);

// Or iterate all joysticks
manager.all.forEach((joystick, uid) => {
    console.log(uid, joystick);
});

manager.idmanager.uid

The identifier property was renamed to uid for consistency across all layers (factory, collection, joystick).

Before (v0)

console.log(manager.id);

After (v1)

console.log(manager.uid);

manager.ids removed

The ids array was removed. Use manager.all (a Map<Uid, Joystick>) to get joystick identifiers.

Before (v0)

const ids = manager.ids;
ids.forEach((id) => {
    const joystick = manager.get(id);
});

After (v1)

const uids = Array.from(manager.all.keys());
uids.forEach((uid) => {
    const joystick = manager.all.get(uid);
});

// Or simply iterate the map
manager.all.forEach((joystick, uid) => {
    console.log(uid, joystick);
});

move event now fires continuously

In v0, the move event only fired when the joystick’s direction changed. In v1, it fires on every pointer/touch move event while the joystick is active, giving smooth, continuous input data.

Before (v0)move fired sporadically (only on direction changes).

After (v1)move fires at the browser’s pointer event rate (~60Hz), regardless of direction changes. Directional events (dir, plain) still only fire on direction transitions.

Event handler signature

Event handlers now receive a single evt argument. Access data via evt.data.

Before (v0)

manager.on('move', function (evt, data) {
    console.log(data.vector);
});

After (v1)

manager.on('move', function (evt) {
    console.log(evt.data.vector);
});

New: reposition() and automatic ResizeObserver

Collections now automatically watch their zone element with a ResizeObserver. For manual repositioning after layout changes that don’t involve a resize, use manager.reposition().

New: setLogLevel() / getLogLevel()

Control library console output. Default level is 'warning'.

nipplejs.setLogLevel('debug'); // see all internal logs

New: baseDelta in move event data

When follow: true is active, the move event now includes baseDelta: { x, y } — the per-frame displacement of the joystick base as it follows the thumb. This enables separating fine aim (vector) from camera/world panning (baseDelta) in a single joystick.

manager.on('move', (evt) => {
    // Fine aim within joystick radius
    const aim = evt.data.vector;
    // Camera pan when base follows thumb
    const pan = evt.data.baseDelta;
});