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

@lumen-mirror/cli

v0.0.8

Published

CLI for scaffolding and developing Lumen Mirror smart mirror apps.

Readme

@lumen-mirror/cli

Create and run Lumen Mirror smart mirror apps from the terminal.

Lumen Mirror is a TypeScript framework for building mirror widgets as modules with HTML templates and reactive signals. This CLI scaffolds projects, generates modules, and runs dev/build tooling — Vite, SCSS, and decorator support are built in, so you never touch a vite.config.ts.

Install

npm install -g @lumen-mirror/cli

Or use it once without installing:

npx @lumen-mirror/cli new my-mirror

Create a project

lumen new my-mirror
cd my-mirror
npm install
npm run dev

Open the URL printed in the terminal (default http://localhost:5173). You get a working mirror with four starter widgets on a CSS grid — the clock is the main reference example (alarms, routine profiles, voices, focus mode, and localStorage persistence).

Starter modules

| Widget | What it demonstrates | | --- | --- | | clock | Full-featured reference module: (click) template bindings, @if / @for, <dialog> alarm editor, Popover API for new profiles, Web Speech voices, minute-by-minute alarm firing, focus mode. State under dashboard.modules.clock in localStorage. | | weather | Signals, host onClick, cross-module events (weather:selected) | | welcome | Event bus listener (envelope with source), onboarding copy | | news-feed | @for list rendering |

Open the clock gear first — add a routine profile, create an alarm, and pick a voice.

Electron (optional)

Run the same app inside an Electron shell — useful for kiosk-style mirrors:

npm run dev:electron

Window size and display options live in lumen.json under electron.

Day-to-day scripts

| Script | What it does | | --- | --- | | npm run dev | Start the dev server with hot reload | | npm run dev:electron | Dev server + Electron window | | npm run build | Production build to dist/ |

All three delegate to the lumen CLI (serve / build).

Project layout

After lumen new, your app looks like this:

my-mirror/
  lumen.json              # platform config (serve, build, electron)
  index.html
  src/
    main.ts               # bootstraps the mirror
    lumen.config.ts       # typed CSS grid layout
    global.scss           # base styles
    modules/              # one folder per widget
      clock/
      weather/
      welcome/
      news-feed/

src/main.ts

Entry point — loads your layout and modules, then starts the runtime:

import lumenProject from '../lumen.json';
import { bootstrap } from '@lumen-mirror/core';
import appConfig from './lumen.config.js';
import { ClockModule, WeatherModule } from './modules/index.js';

await bootstrap({
  root: lumenProject.root,
  modules: [ClockModule, WeatherModule /* … */],
  config: appConfig,
});

src/lumen.config.ts

Define where widgets sit on the mirror grid. Rows, columns, and cell names are type-checked:

import { defineLayout, defineLumenConfig } from '@lumen-mirror/core';

export default defineLumenConfig({
  layout: defineLayout(3, 4, [
    ['clock', 'clock', '.', 'weather'],
    ['welcome', 'welcome', 'welcome', 'welcome'],
    ['news-feed', 'news-feed', '.', '.'],
  ] as const),
});

Use . for empty cells. Each name must match a module's host.classes entry (e.g. host: { classes: ['clock'] }).

lumen.json

Platform config the CLI reads — like angular.json / project.json. Layout and modules live in TypeScript, not here:

{
  "name": "my-mirror",
  "root": "#app",
  "entry": "src/main.ts",
  "index": "index.html",
  "serve": { "port": 5173, "host": "localhost" },
  "build": { "target": "esnext", "minify": true, "sourcemap": false },
  "electron": { "width": 1080, "height": 1920, "fullscreen": false }
}

Add a module

From your project root:

lumen generate quotes

This creates src/modules/quotes/ with a module class, template, and styles, and adds a barrel export in src/modules/index.ts.

By default it does not add the module to src/main.ts or the grid — use that when the widget is nested inside another module:

<QuotesModule />

If you confirm the prompt, it will also register the module in src/main.ts and src/lumen.config.ts for top-level grid placement.

Inside a module:

import { LumenModule, Module, signal } from '@lumen-mirror/core';

@Module({
  templateUrl: './quotes.template.html',
  styleUrls: ['./quotes.template.scss'],
  host: { classes: ['quotes'] },
})
export class QuotesModule extends LumenModule {
  text = signal('Hello, mirror');

  onClick() {
    this.text.set('Tapped!');
  }
}

Put layout and panel styles on the module host via host.classes — do not repeat that class on a wrapper inside the template (the renderer already applies it to the host element).

Templates use {{ signalName }}, @if, and @for. See @lumen-mirror/core for the full template and signals API.

Commands

| Command | Description | | --- | --- | | lumen new <name> | Scaffold a new mirror app | | lumen generate [name] | Add a module (alias: lumen g) | | lumen serve | Dev server with hot reload | | lumen serve --electron | Dev server + Electron shell | | lumen build | Production build |

Requirements

  • Node.js 20+
  • npm, pnpm, or yarn (for installing scaffolded app dependencies)

Learn more