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

@glowbox/vue

v1.12.0

Published

glowbox components for Vue 3 — <LedGrid> (3D WebGL LED grid), <NixieTube>, <SevenSegment>, <FlipDots>, <SplitFlap>, <NeonSign>, <VfdPanel> and <LcdModule>, over the sibling display cores.

Readme

@glowbox/vue

glowbox components for Vue 3 — one per display core: <LedGrid> (the 3D WebGL LED grid), <NixieTube>, <SevenSegment>, <FlipDots>, <SplitFlap>, <NeonSign>, <VfdPanel> and <LcdModule>, each a thin live-updating wrapper over its sibling core package.

⚡ Open in StackBlitz — a running <LedGrid> + <NixieTube> playground in your browser, no install.

yarn add @glowbox/vue
# peer: vue ^3   (the eight display cores come along as dependencies)

<LedGrid>

<script setup lang="ts">
import { LedGrid, type LedDisplay } from '@glowbox/vue';

const draw = (d: LedDisplay, dt: number) => {
	d.clear();
	d.sphere([4, 4, 4], 3, '#00aaff');
};
</script>

<template>
	<div style="width: 480px; height: 480px">
		<LedGrid
			:size="[8, 8, 8]"
			:draw="draw"
			:led="{ glow: 3, offColor: '#0a0a12' }"
			:camera="{ autoOrbit: true, projection: 'perspective' }"
			:color="{ background: '#000', gain: 1.1 }"
			:interaction="{ zoom: true }"
		/>
	</div>
</template>

| prop | type | notes | | ------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | size | [number, number, number] | grid dims [nx, ny, nz] (changing it resizes in place — no remount) | | draw | (d: LedDisplay, dt: number)=>void | called every frame (dt in seconds); write voxels here | | led | LedOptions | style shape stagger rgb rgbLayout vivid outline outlineColor size offSize glow offColor | | color | ColorOptions | background gain tint | | camera | CameraOptions | yaw pitch distance fov projection autoOrbit orbitSpeed pitchLimits (autoOrbit defaults off under prefers-reduced-motion) | | interaction | InteractionOptions | drag dragSpeed zoom zoomLimits | | quality | QualityOptions | pixelRatio antialias paused fps (frame-rate cap) alpha (transparent canvas; fixed at creation) | | label | string | accessible name for the canvas (aria-label; default 'LED grid') | | oncreate | (d: LedDisplay \| null)=>void | the display on create, null on teardown — bind as :oncreate="fn" (@create would look for onCreate) |

The component expose()s the imperative LedDisplay handle as display on the component ref (snapshot(), stats, setCamera, …) — or take it from oncreate:

<script setup lang="ts">
import { ref } from 'vue';
const grid = ref();
// grid.value?.display?.snapshot()
</script>

<template><LedGrid ref="grid" :size="[8, 8, 8]" /></template>

The grouped props mirror @glowbox/led-grid's options 1:1 and update live. draw is bound as one onFrame subscription — onFrame callbacks stack, so subscribing more via the handle layers on top of draw rather than replacing it. See @glowbox/led-grid for defaults, the voxel API, and colour semantics.

<NixieTube>

<script setup lang="ts">
import { NixieTube } from '@glowbox/vue';
</script>

<template>
	<div style="width: 80px; height: 150px">
		<NixieTube value="7" tube-style="classic" color="#ff6a12" />
	</div>
</template>

| prop | type | notes | | ------------ | ------------------------------- | ---------------------------------------------------------- | | value | string \| number \| null | the lit symbol: 09, :, -, or null/'' for dark | | tubeStyle | 'classic' \| 'slim' \| 'tall' | physical tube style (maps to the core style option) | | color | Color | glow colour (default warm nixie orange) | | glow | number | glow strength 0..1 | | background | Color | tube glass colour | | mesh | boolean | draw the honeycomb anode mesh (default true) | | ghost | boolean | show the unlit cathode stack (default true) | | pixelRatio | number | cap on devicePixelRatio | | label | string | accessible name (aria-label); defaults to the lit symbol | | oncreate | (t: NixieTube \| null)=>void | the tube on create, null on teardown (bind :oncreate) |

Props update live; the tube handle is expose()d as tube (setValue, setOptions, resize, snapshot) — or take it from oncreate. The core's bare mode (transparent canvas for 3D compositing) is core-only — use createNixieTube directly for that. See @glowbox/nixie for defaults + the size-adaptive rendering.

<SevenSegment>

<script setup lang="ts">
import { SevenSegment } from '@glowbox/vue';
</script>

<template>
	<div style="width: 76px; height: 130px">
		<SevenSegment value="7" display-style="vfd" :age="0.4" />
	</div>
</template>

A seven-segment digit over @glowbox/seven-segment — per-segment cross-fades, ageing, LED/VFD materials. value takes 09, -, hex A b C d E F, : (the clock separator — give it a narrow slot), or null for dark; displayStyle ('led' | 'vfd'), dp, color, background, glow, ghost, age (0..1 — dimming, then flicker, then a dead segment), transition (per-segment fade ms), pixelRatio, label mirror the core options and update live; the handle is expose()d as display, or comes through :oncreate. See @glowbox/seven-segment for defaults, the ageing arc, and the geometry export.

<FlipDots>

<script setup lang="ts">
import { FlipDots } from '@glowbox/vue';
</script>

<template>
	<div style="width: 560px; height: 280px">
		<FlipDots :cols="28" :rows="14" :frame="(x, y) => (x + y) % 2" sound />
	</div>
</template>

An electromechanical flip-dot board over @glowbox/flip-dot — physical disc flips, scan-wave stagger, an optional solenoid click. frame takes row-major 0/1 bits (ditherFrame output fits) or an (x, y) => on function — only dots that actually change flip; cols, rows, shape ('disc' | 'square'), onColor, offColor, board, gap, shaded, flipMs, axis, stagger ('scan' | 'random' | 'none'), scanMs, sound (true = 0.5, or a 0..1 volume), pixelRatio, label mirror the core options and update live; the handle is expose()d as board, or comes through :oncreate — the imperative FlipDotBoard (set, setFrame, dotAt/dotRect hit-testing). See @glowbox/flip-dot for defaults and ditherFrame.

<SplitFlap>

<script setup lang="ts">
import { SplitFlap } from '@glowbox/vue';
</script>

<template>
	<div style="width: 640px; height: 80px">
		<SplitFlap :cols="12" text="DEPARTURES" sound />
	</div>
</template>

A Solari split-flap board over @glowbox/split-flap — forward-only drum wraps, perspective card falls, a card-slap. text takes a string ('\n' splits rows) or one string per row; cols, rows, charset (plus per-field drums and per-flap palette — see chromaDrum), card, ink, board, gap, font, shaded, flipMs, sound, pixelRatio, label mirror the core options and update live; the handle is expose()d as board, or comes through :oncreate — the imperative SplitFlapBoard (setLine/setChar, cellAt/cellRect hit-testing). See @glowbox/split-flap for the drum model and the colour drums.

<NeonSign>

<script setup lang="ts">
import { NeonSign } from '@glowbox/vue';
</script>

<template>
	<div style="width: 640px; height: 240px">
		<NeonSign text="OPEN" gas="neon" program="flash" sound />
	</div>
</template>

A glass-tube neon sign over @glowbox/neon — single-stroke tube letterforms, electrode strike sequences, visible unlit glass, transformer hum. A text change re-glasses and strikes on; font ('script' | 'sans' | a custom NeonFont), art (sign artwork from SVG path data), color, gas, wall, polarity ('absorb' inks a pale wall — the light-theme neon), on, lineOn, glow, glass, electrode, age, flicker, tired, program ('steady' | 'flash' | 'chase' | 'reveal'), speed, tubes, align, lineSpacing, letterSpacing, tilt, padding, strikeMs, sound, mains, pixelRatio, label mirror the core options and update live; the handle is expose()d as sign, or comes through :oncreate — the imperative NeonSign (power, jolt, sectionAt/sectionRect hit-testing). See @glowbox/neon for the gases, the art pieces, and the wear arc.

<VfdPanel>

<script setup lang="ts">
import { VfdPanel } from '@glowbox/vue';
import type { VfdElement } from '@glowbox/vue';

const layout: VfdElement[] = [
	{ kind: 'digits', name: 'track', x: 8, y: 8, w: 120, h: 48, chars: 4 },
	{ kind: 'legend', name: 'play', x: 140, y: 8, w: 40, h: 16, text: 'PLAY' }
];
</script>

<template>
	<div style="width: 640px; height: 128px">
		<VfdPanel :frame="[320, 64]" :layout="layout" :values="{ track: 'A-12', play: true }" />
	</div>
</template>

A vacuum-fluorescent panel over @glowbox/vfd — declare the hardware once (frame + layout: digits, legends, bars, icons, scales, dot grids, rules) and drive content through values, by element name: a string/number drives a digits field or a scale cursor, a boolean a legend/icon, a number[] a bars element (only changed entries are pushed — the type is exported as VfdValue). The envelope props (phosphor, filter, zones, brightness, persistence, filament, grid, age, glow, bezel, glass, on, selfTest, pixelRatio, label) update live and never re-compile; a layout change goes through setLayout, the one expensive call. The handle is expose()d as panel, or comes through :oncreate — animated content (setDots, a spectrum's setBars) wants it. See @glowbox/vfd for the element kinds and the envelope physics.

<LcdModule>

<script setup lang="ts">
import { LcdModule } from '@glowbox/vue';
</script>

<template>
	<div style="width: 480px; height: 150px">
		<LcdModule :text="'HELLO\nWORLD'" cursor="block" />
	</div>
</template>

A character LCD module (HD44780-class) over @glowbox/lcd — the family's first reflective display: liquid-crystal response smear, the contrast pot, crosstalk streaks, the boot row of solid blocks. text takes a string ('\n' splits rows) or one string per row — the shutters chase it at crystal speed; cols, rows, panel ('green' | 'blue' | 'white'), backlight, contrast, response, ghost, cursor ('none' | 'line' | 'block'), age, on, boot, bezel, pixelRatio, label mirror the core options and update live; the handle is expose()d as lcd, or comes through :oncreate — the imperative LcdModule (setGlyph for CGRAM custom characters, setCursor, power, cellAt/cellRect hit-testing). See @glowbox/lcd for the panels and the crystal physics.

Using with @glowbox/crt

There is deliberately no <Crt> component: @glowbox/crt's element mode already composites every descendant canvas, so add it as its own dependency and wrap the stage element imperatively:

<script setup lang="ts">
import { createCrtScreen, type CrtScreen } from '@glowbox/crt';
import { NixieTube } from '@glowbox/vue';
import { onMounted, onUnmounted, ref } from 'vue';

const stage = ref<HTMLDivElement | null>(null);
let crt: CrtScreen | null = null;
onMounted(() => (crt = stage.value ? createCrtScreen(stage.value) : null));
onUnmounted(() => crt?.dispose());
</script>

<template>
	<div ref="stage" style="width: 80px; height: 150px">
		<NixieTube value="7" />
	</div>
</template>

Sibling packages with the same components: @glowbox/svelte and @glowbox/react; content helpers in @glowbox/extras. Each component fills its parent; give the parent a size. Live demos: https://eetu.github.io/glowbox/.