
Research
SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.
@derivesome/core
Advanced tools
A lightweight reactive state management library with automatic dependency tracking.
A lightweight reactive state management library with automatic dependency tracking.
Reactivity is built on automatic dependency tracking. When a ref.get() is called inside an effect or derived, that ref registers the running effect as a subscriber. When the ref's value changes, all subscribed effects re-run automatically. This means you never manually declare dependencies — the system infers them at runtime.
ref(value) creates a reactive reference holding a single value.
import { ref } from '@derivesome/core';
const count = ref(0);
count.get(); // read and subscribe (inside an effect/derived)
count.peek(); // read without subscribing
count.set(1); // update value — notifies subscribers only if value changed
count.set(n => n + 1); // functional update
Values are compared with strict equality (===). If the new value is the same as the previous one, no notification is sent.
ref also supports dispose() to remove all subscribers and effects:
count.dispose(); // tears down all subscriptions
import { isReference } from '@derivesome/core';
isReference(count); // true
isReference(42); // false
derived(fn) creates a computed value that re-evaluates automatically when its reactive dependencies change. It is itself a Reference, so it can be used anywhere a ref can.
import { ref, derived } from '@derivesome/core';
const count = ref(0);
const doubled = derived(() => count.get() * 2);
const label = derived(() => `Count is: ${doubled.get()}`);
doubled.peek(); // 0
count.set(5);
doubled.peek(); // 10
label.peek(); // "Count is: 10"
Dependencies are tracked dynamically per evaluation. If a branch is not taken, its refs are not subscribed:
const enabled = ref(false);
const value = ref(42);
const result = derived(() => {
if (!enabled.get()) return -1;
return value.get() * 2; // only subscribed when enabled is true
});
import { isDerived } from '@derivesome/core';
isDerived(doubled); // true
isDerived(count); // false
effect(fn) runs a function immediately and re-runs it whenever any ref.get() called inside it changes.
import { ref, effect } from '@derivesome/core';
const name = ref('Alice');
effect(() => {
console.log('Hello,', name.get());
});
// logs: "Hello, Alice"
name.set('Bob');
// logs: "Hello, Bob"
Effects are the primary way to cause side effects in response to reactive state changes. Unlike derived, they don't return a value.
Every ref implements the Observable interface, which provides observe — a way to subscribe to value changes outside of the effect/derived system.
import { ref } from '@derivesome/core';
const count = ref(0);
const unsubscribe = count.observe((value) => {
console.log('count changed to', value);
});
count.set(1); // logs: "count changed to 1"
unsubscribe(); // stop listening
count.set(2); // nothing logged
observe accepts an optional options object:
count.observe(
(value) => console.log(value),
{
immediate: true, // call the callback immediately with the current value
cleanup: () => { // called when the subscription is removed
console.log('cleaned up');
},
}
);
import { isObservable } from '@derivesome/core';
isObservable(count); // true
pubsub() is the low-level primitive underlying ref. It provides a typed publish/subscribe channel with no built-in value storage.
import { pubsub } from '@derivesome/core';
const ps = pubsub<number>();
const unsub = ps.subscribe((value) => {
console.log('received', value);
});
ps.publish(42); // logs: "received 42"
unsub(); // unsubscribe
ps.publish(99); // nothing logged
ps.dispose(); // remove all subscribers and effects
addEffect registers a function that participates in the reactive context system (re-runs through Context.runEffect):
ps.addEffect(() => {
// re-run as a tracked effect when published
});
ArrayProxy<T> extends the native Array and emits a typed mutation event whenever the array is modified. Useful for building reactive list state.
import { ArrayProxy } from '@derivesome/core';
const items = new ArrayProxy('a', 'b', 'c');
const unsub = items.subscribe((mutation) => {
console.log(mutation);
});
items.push('d');
// { type: 'push', items: ['d'] }
items.pop();
// { type: 'pop', removed: 'd' }
items.splice(0, 1, 'z');
// { type: 'splice', start: 0, deleteCount: 1, removed: ['a'], added: ['z'] }
items.set(0, 'x');
// { type: 'set', index: 0, value: 'x' }
items.sort();
// { type: 'sort' }
items.reverse();
// { type: 'reverse' }
items.dispose(); // remove all subscribers
| Method | Mutation type | Extra fields |
|---|---|---|
push | push | items: T[] |
pop | pop | removed: T | undefined |
shift | shift | removed: T | undefined |
unshift | unshift | items: T[] |
splice | splice | start, deleteCount, removed, added |
sort | sort | — |
reverse | reverse | — |
fill | fill | value, start, end |
copyWithin | copyWithin | target, start, end |
.set(i, v) | set | index, value |
Recursively walks any value (object, array, or primitive) and returns all Reference instances found within it.
import { ref, findRefs } from '@derivesome/core';
const a = ref(1);
const b = ref(2);
findRefs({ a, b, nested: { c: ref(3) } });
// [Reference<1>, Reference<2>, Reference<3>]
findRefs([a, b]);
// [Reference<1>, Reference<2>]
findRefs(42); // []
match(input, pattern) is a structural pattern matching utility. It checks whether input structurally matches pattern, working as a type guard.
import { match } from '@derivesome/core';
// Primitive matching
match('hello', 'hello'); // true
match(42, 42); // true
match(42, 99); // false
// Object structural matching (partial — only pattern keys are checked)
const user = { role: 'admin', name: 'Alice' };
match(user, { role: 'admin' }); // true — narrows type
match(user, { role: 'guest' }); // false
// Array matching (positional)
match([1, 2, 3], [1, 2]); // true (pattern checked index-by-index)
// Type narrowing
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; side: number };
function area(shape: Shape): number {
if (match(shape, { kind: 'circle' as const })) {
return Math.PI * shape.radius ** 2; // shape is narrowed to circle
}
return shape.side ** 2;
}
diff(a, b) computes a list of structural differences between two values. patch(target, diffs) applies those diffs to produce a new value.
import { diff, patch } from '@derivesome/core';
const a = { x: 1, y: 2 };
const b = { x: 1, y: 3, z: 4 };
const diffs = diff(a, b);
// [
// { type: 'changed', path: ['y'], oldValue: 2, newValue: 3 },
// { type: 'added', path: ['z'], newValue: 4 },
// ]
const result = patch({ ...a }, diffs);
// { x: 1, y: 3, z: 4 }
Works recursively on nested objects and arrays:
diff([1, 2, 3], [1, 2, 3, 4]);
// [{ type: 'added', path: [3], newValue: 4 }]
diff({ a: { b: 1 } }, { a: { b: 2 } });
// [{ type: 'changed', path: ['a', 'b'], oldValue: 1, newValue: 2 }]
A simple typed stack used internally by the context system. Exported for external use.
import { Stack } from '@derivesome/core';
const stack = new Stack([1, 2, 3]);
stack.current; // 3 (top of stack)
stack.push(4);
stack.current; // 4
stack.pop(); // 4
stack.current; // 3
FAQs
A lightweight reactive state management library with automatic dependency tracking.
We found that @derivesome/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.

Company News
Socket is proud to join the OpenJS Foundation as a Silver Member, deepening our commitment to the long-term health and security of the JavaScript ecosystem.

Security News
npm now links to Socket's security analysis on every package page. Here's what you'll find when you click through.