npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aalink

v0.0.2

Published

Async JavaScript interface for Ableton Link

Readme

aalink-js

aalink-js is a JavaScript port of aalink, an async interface for Ableton Link, built for interactive multimedia applications running in Node.js.

In aalink-js, beats arrive as awaitable promises rather than callbacks, so timing composes with ordinary control flow - loops, async functions, temporal recursion. The beat can optionally sync with other Link apps and devices on the network.

Installation

npm install aalink

aalink-js is compiled from source at install time and requires a C++ toolchain.

Usage

To connect to a Link session, create a Link object and await link.sync() as follows:

const { Link } = require('aalink');

async function main() {
    const link = new Link(120);
    link.enabled = true;

    for (let i = 0; i < 8; i++) {
        const beat = await link.sync(1);
        console.log('bang!');
    }
}

main();

link.sync(n) returns a Promise scheduled to resolve when Link time reaches the next n-th beat on the timeline.

In the above example, awaiting link.sync(1) will pause and resume the main function at beats 1, 2, 3, and so on.

Keep in mind that awaiting sync(n) does not cause a function to sleep for the given number of beats. Regardless of the moment when the function is suspended, it will resume when the next closest n-th beat is reached on the shared Link timeline, e.g. awaiting for sync(2) at beat 11.5 will resume at beat 12.

Non-integral beat syncing is supported. For example:

await link.sync(1/2); // resumes at beats 0.5, 1, 1.5...
await link.sync(3/2); // resumes at beats 1.5, 3, 4.5...

Sync events can be scheduled with an offset (also expressed in beats) by passing a second argument to sync(). Offset can be either positive or negative. Use this to add groove to the function rhythm.

async function arpeggiate() {
    for (let i = 0; i < 16; i++) {
        const swing = i % 2 === 1 ? 0.25 : 0;

        await link.sync(1/2, swing);
        console.log('###', i);

        await link.sync(1/2, 0);
        console.log('@@@', i);
    }
}

Combine synced functions to run in series or concurrently:

const { Link } = require('aalink');

async function main() {
    const link = new Link(120);
    link.enabled = true;

    async function sequence(name) {
        for (let i = 0; i < 4; i++) {
            await link.sync(1);
            console.log('bang!', name);
        }
    }

    await sequence('a');
    await sequence('b');

    await Promise.all([sequence('c'), sequence('d')]);
}

main();

Limitations

aalink-js aims to be punctual, but it is not 100% accurate due to the processing delay in the internal scheduler and the uncertainty of event loop iterations timing.

For convenience, the numerical values of promises returned from sync() aren't equal to the exact beat time from the moment the promises are resolved. They correspond to the previously estimated resume times instead.

let b;
b = await link.sync(1); // b will be 1.0, returned at beat 1.00190
b = await link.sync(1); // b will be 2.0, returned at beat 2.00027
b = await link.sync(1); // b will be 3.0, returned at beat 3.00005

License

Copyright (c) 2026 Artem Popov [email protected]

aalink-js is licensed under the GNU General Public License (GPL) version 3. You can find the full text of the GPL license in the LICENSE file included in this repository.

aalink-js includes code from node-addon-api and Ableton Link.

node-addon-api

Copyright (c) 2017 Node.js API collaborators

node-addon-api license

Ableton Link

Copyright 2016, Ableton AG, Berlin. All rights reserved.

Ableton Link license