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

@kano/stem-daw

v0.1.2

Published

Stem DAW UI — React components, controller, and stores for the STEM beat-quantized DAW. Built on top of @kano/stem-web-audio-player.

Readme

@kano/stem-daw

Stem DAW UI — React components, controller, and stores for the STEM beat-quantized DAW. Renders the full DAW timeline, transports, sample search, autotune & beats lab panels. Builds on top of the audio engine that ships separately as @kano/stem-web-audio-player (this package bundles the engine internals it needs, so you do not have to install the engine package alongside).

This package is consumed by stem-player-rd behind the /studio route. The same source tree also builds the standalone DAW web app at daw.html (see vite.config.daw.ts).

CONSTRAINT Publishing is purely a packaging change. The runtime behaviour — DAWView, the DAWController state machine, the StemFmMixConfig import contract — is identical to the standalone build.


Local development (same pattern as @kano/stem-web-audio-player)

This is the workflow we use day-to-day. No npm publish required.

Option A — sibling file: install (recommended in the monorepo)

With stem-player-rd and stem-studio as siblings under ~/Code/:

# stem-studio — build the library once, rebuild after DAW changes
cd stem-studio
yarn install
yarn build:lib
# optional: rebuild on save
yarn watch

# stem-player-rd — point at the sibling package (package.json):
#   "@kano/stem-daw": "file:../stem-studio"
cd ../stem-player-rd
npm install
STEM_DAW_LOCAL=1 npm run prod   # hot-reload from stem-studio *source*

file:../stem-studio resolves through this repo's package.json exportsdist/. Run yarn build:lib (or yarn watch) whenever you change DAW code and are not using STEM_DAW_LOCAL=1.

Option B — yarn link

# stem-studio
yarn link
yarn install && yarn build:lib && yarn watch

# consumer (e.g. stem-player-rd)
yarn link @kano/stem-daw
yarn install
yarn prod   # or your app's dev script

Option C — live source in the consumer (like STEM_ENGINE_LOCAL)

In stem-player-rd, set STEM_DAW_LOCAL=1 or VITE_STEM_DAW_LOCAL=1. Vite aliases @kano/stem-daw/* to ../stem-studio/src/daw/* and serves worklets from stem-studio/public/workers/ — no rebuild between edits.


Install from npm (when published)

yarn add @kano/stem-daw
yarn add react@^19 react-dom@^19 react-router-dom@^7 zustand@^5

Peer dependencies (must be provided by the consumer)

| Package | Range | Why | | ------------------ | ------- | ------------------------------------------------------ | | react | ^19 | DAW UI | | react-dom | ^19 | DAW UI | | react-router-dom | ^7 | Used by some panels for in-app navigation | | zustand | ^5 | DAW stores; must be the same instance as your app |

Other heavyweight deps (d3, framer-motion, hls.js, @spotify/basic-pitch, the Radix primitives, …) ship as regular dependencies — npm/yarn installs them transitively.

The DAW does not add @kano/stem-web-audio-player to its peer deps: the engine internals the DAW needs are bundled into this package's dist/. Consumers that also use the engine directly (e.g. stem-player-rd's session view) install it separately; the two copies are intentional and isolated.


Exports map

Sub-path imports match the layout stem-player-rd consumes:

import { DAWView }                  from '@kano/stem-daw/components/DAWView';
import { DAWController }            from '@kano/stem-daw/engine/daw-controller';
import { fetchTrackForDAW }         from '@kano/stem-daw/services/track-search-api';
import { useDAWSessionStore }       from '@kano/stem-daw/store/daw-session-store';
import { useDAWAuthStore }          from '@kano/stem-daw/store/daw-auth-store';
import {
    importStemFmMixConfig,
    type StemFmMixConfig,
}                                   from '@kano/stem-daw/engine/daw-import-stem-fm-config';

// Optional barrel — everything above plus extra primitives:
import { DAWView, DAWController } from '@kano/stem-daw';

The full machine-readable map lives in package.json under "exports".


Worklets — required runtime setup

DAWController boots four AudioWorklets that the browser fetches by URL at start-up:

  • /workers/daw-stem-processor.js
  • /workers/realtime-pitch-shift-processor.js (Rubberband)
  • /workers/phase-vocoder3.js (mobile fallback)
  • /workers/buffer-player-processor-202602.lavv8e32-ts.js

The package ships these files in dist/workers/. You must serve them at the matching /workers/<name>.js paths or the DAW will fail to initialise. Pick one of the two strategies below.

Option A — Vite plugin (recommended)

// vite.config.ts
import { defineConfig } from 'vite';
import { dawWorklets } from '@kano/stem-daw/vite';

export default defineConfig({
  plugins: [dawWorklets()],
});

What it does:

  • Dev (vite): middleware streams the worklet files out of node_modules/@kano/stem-daw/dist/workers/ at /workers/<name>.js.
  • Build (vite build): the same files are emitted into the consumer's dist/workers/ so the production bundle is self-contained.

The plugin never overwrites a same-named file already in the consumer's public/workers/ — host app wins, the DAW only fills gaps. Pass { publicPath: '/custom-workers' } if you serve them under a different URL prefix.

Option B — Asset URL imports

If you'd rather drive the URL yourself (e.g. you bundle the DAW into a non-Vite build), each worklet is reachable through the package's ./workers/* subpath export:

import dawProcessorUrl from '@kano/stem-daw/workers/daw-stem-processor.js?url';
import pitchProcessorUrl from '@kano/stem-daw/workers/realtime-pitch-shift-processor.js?url';
// …
// Then make sure your bundler emits those URLs at /workers/<name>.js,
// or override DAWController's worklet-path constants at startup.

stem-player-rd currently uses Option A.


Local development against a consumer (yarn link)

Iterating on the DAW UI while running it inside stem-player-rd:

# in stem-studio (this repo)
yarn install
yarn build:lib
yarn link

# in stem-player-rd
yarn link @kano/stem-daw
yarn dev

yarn build:lib runs tsup + the worklet copy step (see scripts/copy-daw-workers.mjs). Re-run it after any change you want to hot-pick up in the linked consumer.

You can also point a single consumer at a sibling working copy via its own Vite alias instead of linking globally — that's how stem-player-rd's vite.config.ts already wires the @studio alias when the submodule is present.


Internal labs (Beat Lab, pitch / autotune)

These features are off in the default @kano/stem-daw build (no Beat Lab, no Autotune Lab, no pitch inspector, no key badge in the transport, no beat-grid nudge). They are not shipped in dist/workers/analysis-worker.js either.

Enable for local / internal builds only:

# library build (tsup)
DAW_INTERNAL_LABS=1 yarn build:lib

# standalone DAW app (vite)
VITE_DAW_INTERNAL_LABS=1 yarn dev

# password unlock in standalone (labs UI bundled, hidden until unlock)
VITE_DAW_INTERNAL_LABS_PASSWORD=your-secret yarn dev

Publish workflow

Releases run from .github/workflows/publish.yml on tag push (v<major>.<minor>.<patch>). The workflow:

  1. Checks the tag version matches package.json's version.
  2. yarn install --frozen-lockfile.
  3. yarn build:lib (tsup + worklet copy).
  4. Sanity-checks every entry in the exports map exists in dist/.
  5. npm publish --access public --provenance using secrets.NPM_TOKEN.

To cut a release:

yarn version --new-version 0.2.0   # bumps package.json + creates the tag
git push --follow-tags

Manual dispatch is also supported via the Run workflow button (useful for re-publishing the same version after a build infra fix).


Verifying a build before publishing

yarn build:lib
npm pack                            # produces kano-stem-daw-<version>.tgz

# in a fresh vite app:
yarn add ../path/to/kano-stem-daw-0.1.0.tgz
yarn add react@^19 react-dom@^19 react-router-dom@^7 zustand@^5

Then mount <DAWView />, confirm the worklets resolve from /workers/*, and that import('@kano/stem-daw/engine/daw-controller') yields a typed DAWController class.


Non-goal

This package does not absorb the audio engine. @kano/stem-web-audio-player stays a separate package with its own publish pipeline. Reasons:

  • The engine is reusable headless (e.g. stem-player-rd's session view streams without ever mounting a DAW).
  • The DAW is React UI that depends on a specific stack (Radix, framer, etc.) that engine consumers don't want pulled in.

Keep them separate.