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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bbx-audio/nectar

v0.2.0

Published

Collection of JUCE-y modules for building web-based plugin GUIs 🧃

Readme

@bbx-audio/nectar

@bbx-audio/nectar: v0.2.0 Build

Collection of JUCE-y modules for building web-based plugin GUIs 🧃

Overview

nectar is primarily a TypeScript wrapper around the JUCE javascript code that is used for building WebView-based GUIs. It also contains a number of other classes and utilities for things like parameter management, event handling, errors, and math.

This library is framework-agnostic, so feel free to use it in any web-based project 🍻

Installation

# NPM
npm i @bbx-audio/nectar

# Yarn
yarn add @bbx-audio/nectar

Usage

Please refer to the documentation for a comprehensive overview of this library.

Initialization

The juce module contains code that needs to be executed early in your program so that the communication with the JUCE backend is initialized properly.

This is done by simply adding an extra import statement to the top of your frontend's entrypoint file:

// In an entrypoint file e.g., main.ts or index.ts

import '@bbx-audio/nectar/init'

Errors

The error module contains the Result type, which generally helps improve error handling.

It does this by wrapping the result of a function call in a structure that either contains the result as expected or the error that occurred during the function's execution.

import { Result } from '@bbx-audio/nectar'

function divide(a: number, b: number): Result<number> {
    if (b === 0) {
        return [null, new Error('Unable to divide by zero')]
    } else {
        return [a / b, null]
    }
}

const [result, error] = divide(1, 0)
if (error) {
    // Handle the error
} else {
    // Proceed with the result
}

Events

The event module contains a class that allows you to register listener callbacks that are executed when global window and DOM events are emitted. This has two main benefits:

  • Increased performance by limiting the number of actual event listeners to one instead of several since you do not have to add the listeners in each component.
  • Improved developer experience by making it easier to subscribe and manage subscriptions to events.
import { GlobalEventManager } from '@bbx-audio/nectar'

const unsubscribeToClick = GlobalEventManager.subscribeToClick((event: MouseEvent) => {
    // Do something when the mouse is clicked.
})

// Be sure to invoke the unsubscribe closure that we get as a result of subscribing to the event.
unsubscribeToClick()

// You can also subscribe to key-based events.
const unsubscribeToEnterKey = GlobalEventManager.subscribeToKey('Enter', (pressed: boolean, event: KeyboardEvent) => {
    if (pressed) {
        // Do something when the key is pressed.
    } else {
        // Do something when the key is not pressed (after being pressed).
    }
})

// Cleanup the subscription later.
unsubscribeToEnterKey()

Parameters

The parameter module contains the classes and utilities to properly setup bidirectional communication with the JUCE backend.

Parameter Types

There are three different types of parameters:

  • Boolean - A yes or no choice, represented by a boolean value internally.
  • Choice - A selection among multiple choices, represented by an integer value internally.
  • Float - A decimal number, represented by a float value internally.

You can subscribe to a parameter of any type to register callbacks when its internal value is updated. This is useful when making sure the UI elements are in-sync with the backend values.

React:

import { IBooleanParameter, ParameterChangeSource } from '@bbx-audio/nectar'

interface IToggleButtonProps {
    parameter: IBooleanParameter
}

const ToggleButton = ({ parameter }: IToggleButtonProps) => {
    const [isToggled, setIsToggled] = useState(parameter.getValue())

    useEffect(() => {
        const unsubscribe = parameter.subscribe((value, source) => {
            if (isToggled !== value) {
                setIsToggled(value)
            }
        })
        return () => unsubscribe()
    }, [])

    function onClick(): void {
        parameter.setValue(!isToggled, ParameterChangeSource.Frontend)
    }

    return (
        <button onClick={onClick}>
            {isToggled ? 'On' : 'Off'}
        </button>
    )
}

Svelte:

<script lang="ts">
    import { IBooleanParameter, ParameterChangeSource } from '@bbx-audio/nectar'
    
    interface IToggleButtonProps {
        parameter: IBooleanParameter
    }
    
    let { parameter }: IToggleButtonProps = $props()
    
    let isToggled = $state(parameter.getValue())
    
    $effect(() => {
        const unsubscribe = parameter.subscribe((value, source) => {
            if (isToggled != value) {
                isToggled = value
            }
        })
        return () => unsubscribe()
    })
    
    function onClick(): void {
        parameter.setValue(!isToggled, ParameterChangeSource.Frontend)
    }
</script>

<button onclick={onClick}>
    {isToggled ? 'On' : 'Off'}
</button>

Parameter Manager

The ParameterManager is a global object that handles backend communication for each parameter that is registered with it. You can register parameters individually or call a special method that loads parameter data from the backend.

:warning: Do NOT call the initializeParameters method to unless the backend has been properly setup to pass parameter configuration information to the frontend in JSON format.

import { ParameterManager, ParameterType } from '@bbx-audio/nectar'

// Create the parameter manager
const manager = new ParameterManager()

// Register a simple boolean parameter for toggling mono on and off
const monoParameter = manager.registerParameter<ParameterType.Boolean>({
    id: 'MONO',
    name: 'Mono',
    type: ParameterType.Boolean,
    defaultValue: false,
})

// Pass your mono parameter to a component, like a toggle button
// ...

// Be sure to clean up the manager as well
manager.cleanup()

Contributing

This project is open and welcoming of outside contributions! There are multiple ways you can contribute:

  • File a bug report if you encounter buggy or erroneous behavior so we can get it fixed ASAP.
  • Open a pull request if you have some changes you would like to make to the library. Every pull request MUST be associated with a GitHub issue!