@arcanejs/toolkit
v8.0.0
Published
Build web-accessible control interfaces for your long-running Node.js processes
Readme
@arcanejs/toolkit
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/toolkitIf you use the default Arcane frontend renderer, install React peers:
npm install react@^19.2.0 react-dom@^19.2.0Quick 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 likeHUE_GRADIENTandIDMap
startArcaneFrontend(...) supports:
renderers: frontend component renderer listthemeRootProps?: 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 portexpress: attaches websocket handling + route mounting to existing Express/HTTP servermanual: gives direct access toServerfor 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 titlepath: string(default:/): route prefix where Arcane UI is servedlog?: 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 tomaterial-symbols-outlined.woff2when auto-resolution is not possibleadditionalFiles?: Record<string, () => Promise<{ contentType: string; content: Buffer }>>: additional static files served from the toolkit path. Keys are relative request paths (for examplestyles/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 exposestimeDifferenceMsandlastPingMs.
Important constraint:
pathmust 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 \
--sourcemapImport @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 connectsclosed-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:
Buttonuses request/response call flow (pressaction)SwitchandSliderButtonsupport controlled and uncontrolled usageTextInputupdates value from browser messagesGroupsupports editable titles and collapsible defaults (open,closed,auto)Tabsonly acceptsTabchildren
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
@arcanejs/react-toolkit: React renderer for composing server-side component trees@arcanejs/toolkit-frontend: browser renderer components and stage context@arcanejs/protocol: wire protocol types@arcanejs/diff: JSON diff/patch engine
Examples
- React examples: https://github.com/ArcaneWizards/arcanejs/tree/main/examples/react
- Core API examples (no React renderer): https://github.com/ArcaneWizards/arcanejs/tree/main/examples/core
- Custom namespace end-to-end example: https://github.com/ArcaneWizards/arcanejs/tree/main/examples/custom-components
