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

@signal-tree/solid

v15.3.0

Published

Solid observation for SignalTree.

Readme

@signal-tree/solid

SignalTree state, using Solid's own reactivity.

State behaves the same here as in every other SignalTree package: entity identity, transactions, undo, external updates and reactive publication all follow the same rules. This package decides only how that state becomes something Solid can track — leaves are real Solid accessors, so they go straight into createMemo, createEffect and JSX.

(In architecture terms the kernel holds semantic authority and this package is its physical realization; see the glossary if you meet that vocabulary elsewhere.)

npm i @signal-tree/solid solid-js

Solid 1.9 or newer is required as a peer dependency.

The canonical v15 model and composition guidance ships with this package as llms.txt.

Usage

Leaves are Solid accessors. Read by calling; write with .set().

import { signalTree } from '@signal-tree/solid';
import { createEffect } from 'solid-js';

const tree = signalTree({ count: 0, user: { name: 'Ada' } });

createEffect(() => console.log(tree.$.count()));

tree.$.count.set(1);
tree.$.user.name.set('Grace');

Collections keep stable identity per subject, not per key:

import { entityMap, signalTree } from '@signal-tree/solid';

const tree = signalTree({ rows: entityMap<{ id: number; name: string }>({}) });
tree.$.rows.setAll([{ id: 1, name: 'a' }]);

const row = tree.$.rows.byId(1);
tree.$.rows.updateOne(1, { name: 'b' });
row?.(); // { id: 1, name: 'b' }

// A removed subject does not come back when its key is reused.
tree.$.rows.removeOne(1);
tree.$.rows.addOne({ id: 1, name: 'different row' });
row?.(); // undefined — the old subject is gone, not renamed

How it realizes state

createSignal supplies exactly what the adapter seam asks for: a tracked getter and a setter. Per-subject invalidation uses one signal and a reader, and the adapter both creates and advances it — the kernel never writes a framework-owned object.

Signals are created with equals: false on purpose. Equality is the kernel's, not Solid's. The kernel has already decided whether a change is publishable by the time this package hears about it, so letting Solid suppress a notification on value equality would drop invalidations the kernel intended.

Derived cells are created lazily. Solid's createMemo evaluates eagerly, and the kernel builds derived cells while a collection is still initializing — an eager memo would run before that initialization finished.

Testing a Solid app that uses SignalTree

Solid's reactivity needs its compiler. Without vite-plugin-solid, createEffect never runs and reactivity assertions pass while observing nothing:

// vitest.config.ts
import solid from 'vite-plugin-solid';

export default defineConfig({
  plugins: [solid()],
  resolve: { conditions: ['development', 'browser'] },
});

Known limitation

A Solid store proxy is not valid construction input. Pass a plain snapshot:

import { unwrap } from 'solid-js/store';

const tree = signalTree({ data: structuredClone(unwrap(store)) });

@signal-tree/vue rejects the equivalent mistake with a diagnostic. This package does not yet, and the guard is deliberately absent rather than present and unproven: under test, unwrap inside this package and createStore in a consumer resolve to different solid-js instances, so the check silently fails to fire. Shipping a guard that cannot be demonstrated to work reads as protection that is not there. Tracked for a follow-up release.

License

Apache-2.0