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

@openfantasymap/lcars-core

v0.2.3

Published

Core LCARS (Star Trek Library Computer Access/Retrieval System) component library: themeable Stylus/CSS + a dependency-free data-binding runtime. Framework wrappers: @openfantasymap/lcars-react, @openfantasymap/lcars-ngx.

Readme

@openfantasymap/lcars-core

A reusable, themeable LCARS (Star Trek Library Computer Access/Retrieval System) component library, authored in Stylus and documented in Storybook.

It covers the full LCARS vocabulary:

| Category | Components | |----------|-----------| | Primitives | elbow, bar (h/v + end-caps + titles), bracket/frame, text box & readout | | Tools | button, toggle switch, slider (h/v), keypad, status indicator, d-pad | | Systems | radial gauge, bar graph / equalizer, data cascade, warp core, condition alert | | Navigation | sidebar nav, tabs, breadcrumb | | Ship nav (CONN) | bearing compass, sensor scanner (radar), stellar map, helm console | | Engineering | EPS conduit, power distribution, master systems display (MSD) | | Communications | comms/channel panel, signal waveform, incoming-hail banner | | Transporter | emitter pad platform, materialization chamber (data-driven --progress) | | Overview | general schematic from your own annotated SVG (status + live binding) |

Plus foundations: a themeable colour palette, condensed typography, a flex layout kit, the LCARS sizing grid, and an app-shell scaffold.


The @openfantasymap/lcars-* family

| Package | What | Folder | |---------|------|--------| | @openfantasymap/lcars-core | this package — themeable Stylus/CSS + optional data-binding runtime (/js) | lcars-lib/ | | @openfantasymap/lcars-react | React components + hooks (signals via useSyncExternalStore) | lcars-react/ | | @openfantasymap/lcars-ngx | Angular standalone components + signal store | lcars-ngx/ |

The wrappers add nothing visual — they map framework props/signals onto this package's CSS classes and --lcars-* variables, and bridge the core store. Use the core directly for static HTML, Vue, Svelte, etc.

Why Stylus + framework-agnostic CSS?

The library ships as plain CSS classes driven by CSS custom properties. There is no required JS runtime and no framework dependency, so it drops into Angular, React, Vue, Svelte, or static HTML alike. Stylus is the authoring language; you can consume either the compiled CSS or the Stylus source (tokens + mixins) to compose your own widgets.

Install

npm install            # dev: pulls Storybook + Stylus

Node: the toolchain targets Node ≥ 16 (Storybook 7 + Vite 4). This repo's sandbox runs Node 16.20.2.

Usage

Wrap your UI in a .lcars element (this is where the theme variables and the condensed font live), then use the component classes:

<div class="lcars">
  <button class="lcars-button lcars-button--rounded lcars-button--primary">
    Engage
  </button>
</div>

Option A — compiled CSS

<link rel="stylesheet" href="node_modules/@openfantasymap/lcars-core/dist/lcars.css" />

npm run build produces dist/lcars.css (minified) and dist/lcars.expanded.css (readable).

Option B — Stylus source

// your-app.styl
@import '@openfantasymap/lcars-core/src/index'

Option C — compose with the tokens + mixins

@import '@openfantasymap/lcars-core/src/lib/tokens'
@import '@openfantasymap/lcars-core/src/lib/mixins'

.my-corner
  lcars-elbow(left-bottom, 12rem, 5rem, 1.5rem, 9rem, 'accent')

Theming

Every colour and metric is a CSS custom property on .lcars. Override any of them on a .lcars ancestor — no recompile needed:

<div class="lcars" style="--lcars-primary:#66ccff; --lcars-secondary:#cc3366;">
  …everything re-skins…
</div>

Semantic roles: --lcars-primary, --lcars-secondary, --lcars-tertiary, --lcars-accent, --lcars-muted, --lcars-danger, --lcars-warning, --lcars-success. Named Okuda stops are also exposed (--lcars-golden-tanoi, --lcars-periwinkle, --lcars-lilac, --lcars-hopbush, …).

Components ship a --<role> modifier for each role, e.g. lcars-button--danger, lcars-gauge--periwinkle, lcars-bracket--accent.

Drop-in for lcars-mqtt: the existing Angular app themes via --main-color / --secondary-color / --tertiary-color. Those names are aliased to the new roles, so the library inherits that app's theme verbatim.

Theme presets (eras & factions)

Add a theme class on the same element as .lcars to re-skin everything:

<div class="lcars lcars-theme-klingon"> … </div>

| Family | Classes | |--------|---------| | Federation eras | lcars-theme-tng · lcars-theme-picard · lcars-theme-ds9 · lcars-theme-voyager | | Factions | lcars-theme-klingon · lcars-theme-romulan · lcars-theme-cardassian · lcars-theme-ferengi |

In Storybook, the Theme toolbar (top bar) switches the theme for every story. Add your own by defining a .lcars-theme-x class that overrides the roles.

Real-time data binding

The CSS is already data-driven through CSS custom properties (--value, --heading, --warp, --load, …). The optional JS runtime keeps the DOM in sync with a live feed — no framework, no dependencies:

import { createStore, bind, simulate } from '@openfantasymap/lcars-core/js';

const store = createStore({ shields: 98, warp: 6.2, redAlert: false });
const unbind = bind(document.querySelector('.lcars'), store);

store.set('shields', 91);            // bound DOM updates instantly
store.set({ warp: 7.4, redAlert: true });

Annotate markup with data-bind-*:

<div class="lcars-gauge" data-bind-style="--value: shields">
  <span class="lcars-gauge__value" data-bind-text="shields|round"></span>
</div>
<div class="lcars-helm" data-bind-style="--warp: warp; --impulse: impulse"></div>
<span class="lcars-indicator"
      data-bind-class="lcars-indicator--alert: redAlert; lcars-indicator--online: !redAlert">…</span>
  • data-bind-style="--prop: key|fmt; …" — set CSS variables
  • data-bind-text="key|fmt" — set text content
  • data-bind-class="className: key; other: !key" — toggle classes (truthy / negated)
  • data-bind-attr="name: key|fmt" — set attributes

Formatters: round · fixed1 · fixed2 · pct · pad2 · pad3 · warp · upper (extend via import { formatters } from '@openfantasymap/lcars-core/js').

Wiring a real feed (transport-agnostic — map any source to store.set):

// MQTT (e.g. the sibling lcars-mqtt app)
const TOPICS = { 'ship/shields': 'shields', 'ship/heading': 'heading' };
client.on('message', (topic, buf) => store.set(TOPICS[topic], Number(buf)));

// or WebSocket / EventSource / poll → same store.set(...)

simulate(store, spec) drives random-walk values for demos and tests (see the Realtime/Bridge Ops story).

Overview — bring your own annotated SVG

The Overview component turns any SVG (deck plan, systems diagram, EPS grid…) into a themed, interactive, data-driven schematic. Annotate elements in your SVG:

<rect data-lcars-region data-lcars-id="reactor" data-lcars-label="M/ARA Reactor"
      data-lcars-status="nominal"
      data-bind-attr="data-lcars-status: reactorState"
      x="170" y="105" width="80" height="50" rx="8"/>

| Annotation | Effect | |------------|--------| | data-lcars-region | mark as an interactive/status region | | data-lcars-id | logical id (for setStatus / select events) | | data-lcars-label | name → legend, tooltip, aria-label | | data-lcars-role="primary" | static fill from a theme role (re-skins with the theme) | | data-lcars-status="critical" | status fill: nominal · warning · critical · offline (critical pulses) | | data-bind-attr / data-bind-* | optional live binding to a store |

Region colours are pure CSS (theme-aware); the interpreter reads the annotations, uses the SVG's own data-lcars-status values as the defaults, builds a legend, and makes regions keyboard-focusable + clickable.

import { loadOverview, createStore } from '@openfantasymap/lcars-core/js';

const ov = await loadOverview(hostEl, svgMarkupOrUrl, {
  onSelect: (id, el) => console.log('selected', id),
});
ov.setStatus('reactor', 'critical');   // recolour a region
ov.statuses();                         // defaults read from the SVG

// Go live with one call — auto-seeds a store from the SVG's data-bind-attr
// annotations + their default statuses, binds it, and returns it:
const store = ov.connect();
store.set('reactorState', 'critical'); // the SVG updates instantly
// (or pass your own store: ov.connect(createStore({...})))

loadOverview accepts SVG markup, an <svg> element, or a .svg URL (fetched). See the Overview/Schematic stories (interpreted + realtime).

Storybook

npm run storybook        # dev server on http://localhost:6006
npm run build-storybook  # static build into storybook-static/

Every component has a Playground story with live controls (colour role, size, state, value, label, …) plus example compositions. The renderer is @storybook/html-vite, which compiles the Stylus source on the fly.

Project layout

src/
  index.styl                 # single entry point (imports everything)
  lib/
    tokens.styl              # palette + metrics → CSS custom properties
    themes.styl              # era + faction theme presets (.lcars-theme-*)
    mixins.styl              # role(), lcars-elbow(), pill(), color-variants()…
    base.styl                # reset + typography (scoped to .lcars)
    layout.styl              # row / column / panel / app-shell
    grid.styl                # lcars-u-N / lcars-vu-N sizing units
    components/
      elbow · bar · bracket · textbox · button
      toggle · slider · keypad · indicator
      gauge · bargraph · datacascade · warpcore · alert
      nav · tabs · breadcrumb
      compass · scanner · starmap · helm    # ship navigation (CONN)
      conduit · power · msd                  # engineering
      comms · waveform · hail                # communications
      overview                               # annotated-SVG schematic
      transporter
  js/                        # optional data-driven runtime (no deps)
    store.js · bind.js · format.js · simulate.js · overview.js · index.js
stories/                     # one *.stories.js per component
.storybook/                  # main.js · preview.js · preview-head.html
dist/                        # built CSS (after `npm run build`)

Scripts

| Script | Does | |--------|------| | npm run build | compile minified + expanded CSS into dist/ | | npm run build:css | minified dist/lcars.css only | | npm run watch:css | recompile on change | | npm run storybook | run Storybook dev server | | npm run build-storybook | static Storybook build |

Architecture notes

  • .lcars carries the theme (custom properties) and the typographic reset. Component classes are top-level (.lcars-button, not .lcars .lcars-button) so they stay low-specificity and work even outside a .lcars wrapper — they just fall back to the built-in colour values via var(--x, fallback).
  • Animations are pure CSS. Warp core, equalizer, data cascade, alert klaxon and the transporter beam all run without JS.
  • Data-driven widgets (slider, gauge, bar graph) are driven by a --value (0–100) custom property, so you bind one number from live telemetry.

Releasing

Publishing is automated by .github/workflows/publish.ymlnpm (public), with provenance. Add the repo secret NPM_TOKEN (an npm automation token), then ship by pushing a version tag:

npm version patch            # or minor / major — updates package.json
git push --follow-tags       # tag v<version> triggers the publish workflow

The workflow guards that the tag matches package.json. Publish core first, then the wrappers (lcars-react / lcars-ngx) — they build against the published core.

License

MIT.