{"id":39663423,"url":"https://github.com/blackboxaudio/nectar","last_synced_at":"2026-01-18T09:26:11.624Z","repository":{"id":311242796,"uuid":"1042229972","full_name":"blackboxaudio/nectar","owner":"blackboxaudio","description":"Collection of JUCE-y modules for building web-based plugin GUIs 🧃","archived":false,"fork":false,"pushed_at":"2025-09-15T23:09:55.000Z","size":131,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2025-12-29T06:24:55.445Z","etag":null,"topics":["audio-plugin","juce","math","utilities","webview"],"latest_commit_sha":null,"homepage":"https://nectar.bbx-audio.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blackboxaudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-21T17:25:04.000Z","updated_at":"2025-12-14T18:19:49.000Z","dependencies_parsed_at":"2025-08-23T02:49:30.903Z","dependency_job_id":"1b6ed8cb-a5b7-4b6c-98dd-3daddda359f5","html_url":"https://github.com/blackboxaudio/nectar","commit_stats":null,"previous_names":["blackboxaudio/nectar"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/blackboxaudio/nectar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackboxaudio%2Fnectar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackboxaudio%2Fnectar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackboxaudio%2Fnectar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackboxaudio%2Fnectar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blackboxaudio","download_url":"https://codeload.github.com/blackboxaudio/nectar/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blackboxaudio%2Fnectar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28534159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-plugin","juce","math","utilities","webview"],"created_at":"2026-01-18T09:26:11.461Z","updated_at":"2026-01-18T09:26:11.594Z","avatar_url":"https://github.com/blackboxaudio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `@bbx-audio/nectar`\n\n[![@bbx-audio/nectar: v0.2.0](https://img.shields.io/badge/npm-v0.2.0-blue.svg)](https://github.com/blackboxaudio/nectar)\n[![Build](https://github.com/blackboxaudio/nectar/actions/workflows/ci.build.yml/badge.svg)](https://github.com/blackboxaudio/nectar/actions/workflows/ci.build.yml)\n\n\u003e Collection of JUCE-y modules for building web-based plugin GUIs 🧃\n\n## Overview\n\n`nectar` is primarily a TypeScript wrapper around the [JUCE javascript code](https://github.com/juce-framework/JUCE/tree/master/modules/juce_gui_extra/native/javascript) that is used for building WebView-based GUIs. \nIt also contains a number of other classes and utilities for things like parameter management, event handling, errors, and math.\n\nThis library is framework-agnostic, so feel free to use it in _any_ web-based project 🍻\n\n## Installation\n\n```bash\n# NPM\nnpm i @bbx-audio/nectar\n\n# Yarn\nyarn add @bbx-audio/nectar\n```\n\n## Usage\n\nPlease refer to the [documentation](https://nectar.bbx-audio.com) for a comprehensive overview of this library.\n\n### Initialization\n\nThe [`juce`](https://github.com/blackboxaudio/nectar/tree/develop/src/juce) module contains code that needs to be \nexecuted early in your program so that the communication with the JUCE backend is initialized properly.\n\nThis is done by simply adding an extra import statement to the top of your frontend's entrypoint file:\n```typescript\n// In an entrypoint file e.g., main.ts or index.ts\n\nimport '@bbx-audio/nectar/init'\n```\n\n### Errors\n\nThe [`error`](https://github.com/blackboxaudio/nectar/tree/develop/src/error) module contains the `Result` type, which generally helps improve error handling.\n\nIt does this by wrapping the result of a function call in a structure that either contains\nthe result as expected or the error that occurred during the function's execution.\n\n```typescript\nimport { Result } from '@bbx-audio/nectar'\n\nfunction divide(a: number, b: number): Result\u003cnumber\u003e {\n    if (b === 0) {\n        return [null, new Error('Unable to divide by zero')]\n    } else {\n        return [a / b, null]\n    }\n}\n\nconst [result, error] = divide(1, 0)\nif (error) {\n    // Handle the error\n} else {\n    // Proceed with the result\n}\n```\n\n### Events\n\nThe [`event`](https://github.com/blackboxaudio/nectar/tree/develop/src/event) module contains a class that allows you to register listener callbacks that are executed when global\nwindow and DOM events are emitted. This has two main benefits:\n- 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.\n- Improved developer experience by making it easier to subscribe and manage subscriptions to events.\n\n```typescript\nimport { GlobalEventManager } from '@bbx-audio/nectar'\n\nconst unsubscribeToClick = GlobalEventManager.subscribeToClick((event: MouseEvent) =\u003e {\n    // Do something when the mouse is clicked.\n})\n\n// Be sure to invoke the unsubscribe closure that we get as a result of subscribing to the event.\nunsubscribeToClick()\n\n// You can also subscribe to key-based events.\nconst unsubscribeToEnterKey = GlobalEventManager.subscribeToKey('Enter', (pressed: boolean, event: KeyboardEvent) =\u003e {\n    if (pressed) {\n        // Do something when the key is pressed.\n    } else {\n        // Do something when the key is not pressed (after being pressed).\n    }\n})\n\n// Cleanup the subscription later.\nunsubscribeToEnterKey()\n```\n\n### Parameters\n\nThe [`parameter`](https://github.com/blackboxaudio/nectar/tree/develop/src/parameter) module contains the classes and utilities to properly setup bidirectional communication with the JUCE backend.\n\n#### Parameter Types\n\nThere are three different types of parameters:\n- Boolean - A yes or no choice, represented by a boolean value internally.\n- Choice - A selection among multiple choices, represented by an integer value internally.\n- Float - A decimal number, represented by a float value internally.\n\nYou can subscribe to a parameter of any type to register callbacks when its internal value is updated.\nThis is useful when making sure the UI elements are in-sync with the backend values.\n\nReact:\n\n```tsx\nimport { IBooleanParameter, ParameterChangeSource } from '@bbx-audio/nectar'\n\ninterface IToggleButtonProps {\n    parameter: IBooleanParameter\n}\n\nconst ToggleButton = ({ parameter }: IToggleButtonProps) =\u003e {\n    const [isToggled, setIsToggled] = useState(parameter.getValue())\n\n    useEffect(() =\u003e {\n        const unsubscribe = parameter.subscribe((value, source) =\u003e {\n            if (isToggled !== value) {\n                setIsToggled(value)\n            }\n        })\n        return () =\u003e unsubscribe()\n    }, [])\n\n    function onClick(): void {\n        parameter.setValue(!isToggled, ParameterChangeSource.Frontend)\n    }\n\n    return (\n        \u003cbutton onClick={onClick}\u003e\n            {isToggled ? 'On' : 'Off'}\n        \u003c/button\u003e\n    )\n}\n```\n\nSvelte:\n```svelte\n\u003cscript lang=\"ts\"\u003e\n    import { IBooleanParameter, ParameterChangeSource } from '@bbx-audio/nectar'\n    \n    interface IToggleButtonProps {\n        parameter: IBooleanParameter\n    }\n    \n    let { parameter }: IToggleButtonProps = $props()\n    \n    let isToggled = $state(parameter.getValue())\n    \n    $effect(() =\u003e {\n        const unsubscribe = parameter.subscribe((value, source) =\u003e {\n            if (isToggled != value) {\n                isToggled = value\n            }\n        })\n        return () =\u003e unsubscribe()\n    })\n    \n    function onClick(): void {\n        parameter.setValue(!isToggled, ParameterChangeSource.Frontend)\n    }\n\u003c/script\u003e\n\n\u003cbutton onclick={onClick}\u003e\n    {isToggled ? 'On' : 'Off'}\n\u003c/button\u003e\n```\n\n#### Parameter Manager\n\nThe `ParameterManager` is a global object that handles backend communication for each parameter that is registered with it.\nYou can register parameters individually or call a special method that loads parameter data from the backend.\n\n:warning: Do **NOT** call the `initializeParameters` method to unless the backend has been properly setup to pass parameter\nconfiguration information to the frontend in JSON format.\n\n```tsx\nimport { ParameterManager, ParameterType } from '@bbx-audio/nectar'\n\n// Create the parameter manager\nconst manager = new ParameterManager()\n\n// Register a simple boolean parameter for toggling mono on and off\nconst monoParameter = manager.registerParameter\u003cParameterType.Boolean\u003e({\n    id: 'MONO',\n    name: 'Mono',\n    type: ParameterType.Boolean,\n    defaultValue: false,\n})\n\n// Pass your mono parameter to a component, like a toggle button\n// ...\n\n// Be sure to clean up the manager as well\nmanager.cleanup()\n```\n\n## Contributing\n\nThis project is open and welcoming of outside contributions! There are multiple ways you can contribute:\n- [File a bug report](https://github.com/blackboxaudio/nectar/issues) if you encounter buggy or erroneous behavior so we can get it fixed ASAP.\n- [Open a pull request](https://github.com/blackboxaudio/nectar/compare) if you have some changes you would like to make to the library. **Every pull request MUST be associated with a GitHub issue!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackboxaudio%2Fnectar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblackboxaudio%2Fnectar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackboxaudio%2Fnectar/lists"}