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

@arcanejs/toolkit

v8.0.0

Published

Build web-accessible control interfaces for your long-running Node.js processes

Readme

@arcanejs/toolkit

NPM Version

Core server/runtime package for ArcaneJS control panels.

@arcanejs/toolkit provides:

  • A server-side component tree (Group, Button, Switch, etc.)
  • HTTP + WebSocket transport for syncing state to browsers
  • Per-connection tree sync (tree-full + tree-diff)
  • Routing for fire-and-forget messages and request/response calls

Most users should pair this with @arcanejs/react-toolkit, but this package can also be used directly.

Install

npm install @arcanejs/toolkit

If you use the default Arcane frontend renderer, install React peers:

npm install react@^19.2.0 react-dom@^19.2.0

Quick Start (Without React)

import { Toolkit, Group, Button, Label } from '@arcanejs/toolkit';

const toolkit = new Toolkit({
  title: 'My Control Panel',
  path: '/',
});

toolkit.start({
  mode: 'automatic',
  port: 3000,
});

const root = new Group({ direction: 'vertical', title: 'Controls' });
const status = new Label({ text: 'Idle' });
const trigger = new Button({
  text: 'Run',
  onClick: async () => {
    status.setText('Running...');
    await doWork();
    status.setText('Done');
  },
});

root.appendChildren(status, trigger);
toolkit.setRoot(root);

Public API

Top-level exports

  • Toolkit
  • Components: Button, Group, GroupHeader, Label, Rect, SliderButton, Switch, Tab, Tabs, TextInput, Timeline
  • Types: ToolkitOptions, ToolkitConnection, ToolkitRenderContext, ToolkitServerListenerOptions, ToolkitServerListener, AnyComponent

Subpath exports

  • @arcanejs/toolkit/components/*: component classes and types
  • @arcanejs/toolkit/components/base: Base, BaseParent, EventEmitter, related types
  • @arcanejs/toolkit/frontend: browser entrypoint helpers (startArcaneFrontend)
  • @arcanejs/toolkit/util: utility exports like HUE_GRADIENT and IDMap

startArcaneFrontend(...) supports:

  • renderers: frontend component renderer list
  • themeRootProps?: React.HTMLAttributes<HTMLDivElement> (root theme container props)
  • loadingState?: () => ReactNode (custom render output while waiting for initial websocket metadata/tree sync)

Theme switching is handled by Arcane via root classes (theme-auto, theme-dark, theme-light). Theme customization is CSS-only by overriding Arcane CSS variables in your entrypoint stylesheet.

Toolkit Lifecycle

Toolkit.start(...) supports three modes:

  • automatic: creates internal HTTP + WebSocket server on a port
  • express: attaches websocket handling + route mounting to existing Express/HTTP server
  • manual: gives direct access to Server for custom integration

Toolkit.listen(...) is also available when you want direct lifecycle control and a closable listener handle.

Toolkit Options

new Toolkit(options) supports:

  • title?: string: page title
  • path: string (default: /): route prefix where Arcane UI is served
  • log?: Logger: optional logger (debug, info, warn, error)
  • entrypointJsFile?: string: custom frontend bundle path for custom namespaces/components. ArcaneJS expects a same-basename stylesheet (.css) to exist for this entrypoint so styles can be served automatically. Source maps (.js.map, .css.map) are optional and exposed when present.
  • materialIconsFontFile?: string: explicit path to material-symbols-outlined.woff2 when auto-resolution is not possible
  • additionalFiles?: Record<string, () => Promise<{ contentType: string; content: Buffer }>>: additional static files served from the toolkit path. Keys are relative request paths (for example styles/app.css -> /your-path/styles/app.css), and must not start with /.
  • htmlPage?: (context) => string | Promise<string>: custom HTML renderer for the root route. Context includes:
    • coreAssets: URLs for built-in toolkit static assets (materialSymbolsOutlined, entrypointJs, entrypointJsMap, entrypointCss, entrypointCssMap)
    • assetUrls: URL mapping for all static assets by relative path (core + additionalFiles)
    • title, path
  • clockSync?: false | { pingIntervalMs: number }: optional browser/server clock synchronization. When enabled via object options, frontend stage context exposes timeDifferenceMs and lastPingMs.

Important constraint:

  • path must start and end with / (for example: /, /control/)

Building Custom Frontend Entrypoints

When using entrypointJsFile, build your browser bundle with @arcanejs/build-utils:

arcane-build-frontend \
  --entry src/frontend.tsx \
  --outfile dist/custom-entrypoint.js \
  --sourcemap

Import @arcanejs/toolkit-frontend/styles/core.css in the entrypoint so Arcane core styles are included in the emitted .css sidecar.

Events and Connections

Toolkit emits:

  • new-connection: when a browser connects
  • closed-connection: when a browser disconnects

Use toolkit.getConnections() to inspect active connections. Each connection has a stable uuid.

Component Notes

Core components are stateful server objects. Notable interaction behavior:

  • Button uses request/response call flow (press action)
  • Switch and SliderButton support controlled and uncontrolled usage
  • TextInput updates value from browser messages
  • Group supports editable titles and collapsible defaults (open, closed, auto)
  • Tabs only accepts Tab children

Architectural Constraints

  • Single-process architecture by design
  • No built-in authentication/authorization
  • Toolkit.setRoot(...) can only be called once
  • Tree updates are throttled internally and rendered per active connection

Related Packages

Examples