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

@quantajs/lit

v3.0.0

Published

Lit bindings for QuantaJS stores: reactive controllers for web components.

Readme

@quantajs/lit

CI npm

Lit bindings for @quantajs/core: reactive controllers that connect QuantaJS stores to web components. Works with Lit 2 and 3.

Documentation · Example app · Changelog

Install

npm install @quantajs/core @quantajs/lit

Usage

// stores/todos.ts
import { defineStore } from '@quantajs/core';

export const useTodoStore = defineStore('todos', {
    state: () => ({ items: [] as { text: string; done: boolean }[] }),
    getters: {
        remaining: (s) => s.items.filter((t) => !t.done).length,
    },
    actions: {
        add(text: string) {
            this.items.push({ text, done: false });
        },
    },
});
// todo-app.ts
import { LitElement, html } from 'lit';
import {
    QuantaActionsController,
    QuantaController,
    QuantaValueController,
} from '@quantajs/lit';
import { useTodoStore } from './stores/todos';

export class TodoApp extends LitElement {
    // Updates this element only when `remaining` changes.
    private remaining = new QuantaValueController(
        this,
        useTodoStore,
        (s) => s.remaining,
    );

    // Updates this element on any change to the store.
    private todos = new QuantaController(this, useTodoStore);

    // The store, without subscribing: for calling actions.
    private actions = new QuantaActionsController(this, useTodoStore);

    render() {
        return html`
            <p>${this.remaining.value} left</p>
            <button @click=${() => this.actions.store.add('New todo')}>
                Add
            </button>
            <ul>
                ${this.todos.store.items.map((t) => html`<li>${t.text}</li>`)}
            </ul>
        `;
    }
}
customElements.define('todo-app', TodoApp);

No setup is needed in a client-only app: stores resolve against the default container.

Controllers

| Controller | Updates the element on | Use for | | ---------------------------------------------------------- | ----------------------- | --------------------------------------------------------- | | QuantaValueController(host, definition, selector, opts?) | What the selector reads | Most elements; read .value | | QuantaController(host, definition, opts?) | Any change to the store | Elements that read most of a store; read .store | | QuantaActionsController(host, definition, opts?) | Nothing | Elements that only call actions; read .store | | QuantaLocalController(host, definition) | Any change to the store | A store owned by one element, disposed when it is removed |

Create them as class fields, or in the constructor. Subscriptions start when the element connects and end when it disconnects. A local store survives the element being moved in the DOM.

A selector that builds a new object on every run should pass shallow, so an unchanged projection does not update:

import { LitElement } from 'lit';
import { shallow, QuantaValueController } from '@quantajs/lit';
import { useTodoStore } from './stores/todos';

export class TodoSummary extends LitElement {
    private summary = new QuantaValueController(
        this,
        useTodoStore,
        (s) => ({ remaining: s.remaining, total: s.items.length }),
        { equalityFn: shallow },
    );
}

Containers

provideQuantaContainer(this) in an element's constructor gives that element's subtree its own container, including elements in its shadow root. It follows the web components context protocol, so @lit/context works too: quantaContainerContext is the context key.

import { LitElement } from 'lit';
import { provideQuantaContainer } from '@quantajs/lit';

export class AppRoot extends LitElement {
    constructor() {
        super();
        // Created here and disposed when the element is removed.
        provideQuantaContainer(this);
    }
}

Pass { container } to any controller to use a specific container instead. Before an element connects, and during server rendering, controllers resolve against that container or the default one.

DevTools

npm install -D @quantajs/devtools
import { enableDevTools } from '@quantajs/lit';

if (import.meta.env.DEV) {
    enableDevTools({ redact: ['token'] });
    import('@quantajs/devtools').then(({ mountDevTools }) => mountDevTools());
}

License

MIT