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

@excom/neutron

v0.2.0

Published

Element factory of the Nucleus Stack — typed custom elements with effect-based lifecycles

Readme

neutron

Define typed custom elements with effect-based lifecycles — props, events, and compose without rewriting the Custom Elements boilerplate.

Neutron is the element factory of the Nucleus Stack: Neutron({ tag, props }) returns a builder you chain lifecycles onto, then define(). Every Nucleus Kit element is a Neutron element, and so is every element you write yourself.

Features

  • Declarative factory Neutron({ tag, props }).… .define()
  • Typed props Primitives and TokenList reflect to dashed attributes; objects / arrays / elements / promises stay on the instance
  • Effect returns Lifecycles / methods return a POJO (or an array of them) that sets props, emits, listens, calls methods, and styles
  • Fine-grained reactions onPropSet / Unset / Changed / onEffect
  • Events & broadcasts Tag-prefixed custom events, cancelable default actions, channel broadcasts
  • Commands onCommand("--verb") handles the HTML Command API — <button command commandfor> needs no custom element
  • Listener cleanup Listeners added through effects are removed on disconnect and restored on reconnect
  • Compose Combine builders (Neutron.compose) for mixin-style packages
  • Recompose Import a package's raw builder, add / remove lifecycles and methods, then define() it yourself
  • DevTools Neutron.attachDevtools() hooks the Nucleus DevTools extension

Installation

Usage

Beta disclaimer: Neutron automatically defines your element's Typescript types based upon your element config. This is done via complicated internal typing that has a few known issues. These issues will be resolved in the first stable release.

An element owns its own state (attributes) and announces changes (events). It never renders children or reaches into siblings — coordination belongs to Quark. The rules these examples follow are collected in Best Practices and Creating Elements.

import { Neutron } from "@excom/neutron";

export const PressTracker = Neutron({
  tag: "press-tracker",
  props: {
    pressCount: { type: Number, defaultValue: () => 0 }, // reflects ↔ `press-count`
  },
})
  .onEvent("click", ({ pressCount }) => ({
    // effects are declarative instructions, not imperative mutations
    pressCount: pressCount + 1,
    emit: ["press-tracker-press", { detail: { pressCount: pressCount + 1 } }],
  }));

PressTracker.define();
<press-tracker press-count="0">
  <button>Press</button>
</press-tracker>
<!-- `press-tracker[press-count="3"]` is now a CSS / Quark selector -->

Documentation

Defining elements

  • Props — typed props, reflection, TokenList, naming rules
  • Provision — the one property for published rich data
  • TypeScript — global element types, ConstructorType

Behavior

  • Lifecycles — onConnected & co., destructuring, async pitfalls
  • Effects — the object a handler returns
  • Prop reactions — onPropSet / Unset / Changed / onEffect
  • Methods — methods as effectors
  • Events — emits, default actions, broadcasts, listener cleanup
  • Commands — onCommand for --verb commands, the command effect
  • Promise props — onPromiseResolved / Rejected

Composition

  • Compose — stack builders into mixin-style packages
  • Recompose — edit a packaged element before defining it

Runtime

  • Define — define() and class introspection
  • Debug — DevTools hook, loop guard

Examples

State on connect

Neutron({ tag: "ready-flag", props: { isReady: Boolean } })
  .onConnected(() => ({ isReady: true, emit: ["ready-flag-ready"] }))
  .define();

Child element effect across handlers

Assign an element prop, then react to it with a nested effect. Listener callbacks that return effects must be defineMethods methods:

Neutron({
  tag: "focus-host",
  props: {
    inputEl: { type: HTMLInputElement, store: "weak" },
    isFocused: Boolean,
  },
})
  .defineMethods({
    handleFocus: () => ({ isFocused: true, emit: ["focus-host-focus"] }),
    handleBlur: () => ({ isFocused: false }),
  })
  .onConnected((el) => ({
    inputEl: el.querySelector("input"),
  }))
  .onPropSet("inputEl", ({ handleFocus, handleBlur }) => ({
    inputEl: {
      addListeners: [
        ["focus", handleFocus],
        ["blur", handleBlur],
      ],
    },
  }));

Full documentation: https://nucleus.excom.dev/packages/neutron