Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@directive-run/core

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@directive-run/core

The constraint-driven runtime for TypeScript. Declare what must be true — the runtime makes it happen.

latest
Source
npmnpm
Version
1.16.0
Version published
Weekly downloads
2.2K
345.17%
Maintainers
1
Weekly downloads
 
Created
Source

@directive-run/core

npm downloads bundle size CI license

Constraint-driven runtime for TypeScript. Declare requirements, let the runtime resolve them.

  • Auto-tracking derivations – computed values that track their own dependencies, no manual dep arrays
  • Typed constraint/resolver cycle – constraints declare what must be true, resolvers make it true
  • Events – typed event handlers with payloads for imperative actions
  • Plugin architecture – logging, devtools, persistence, and custom lifecycle hooks
  • Framework adapters – first-class bindings for React, Vue, Svelte, Solid, and Lit

Install

npm install @directive-run/core

Quick Start

import { createModule, createSystem, t } from "@directive-run/core";

const counter = createModule("counter", {
  schema: {
    facts: { count: t.number() },
    derivations: { doubled: t.number() },
    events: { increment: {}, reset: {} },
    requirements: {},
  },

  init: (facts) => {
    facts.count = 0;
  },

  derive: {
    doubled: (facts) => facts.count * 2,
  },

  events: {
    increment: (facts) => {
      facts.count += 1;
    },
    reset: (facts) => {
      facts.count = 0;
    },
  },
});

const system = createSystem({ module: counter });
system.start();

system.events.increment();
console.log(system.facts.count);     // 1
console.log(system.read("doubled")); // 2

Derived State

Derivations auto-track which facts they read. No dependency arrays, no manual subscriptions. Derivations can depend on other derivations for composition:

const app = createModule("app", {
  schema: {
    facts: { items: t.array<string>(), filter: t.string() },
    derivations: {
      filtered: t.array<string>(),
      count: t.number(),
      summary: t.string(),
    },
    events: {},
    requirements: {},
  },

  init: (facts) => {
    facts.items = ["apple", "banana", "avocado"];
    facts.filter = "a";
  },

  derive: {
    filtered: (facts) => facts.items.filter((i) => i.startsWith(facts.filter)),
    count: (_facts, derived) => derived.filtered.length,
    summary: (_facts, derived) => `${derived.count} items match`,
  },
});

Constraints and Resolvers

The constraint/resolver cycle is the core of Directive. Constraints declare what must be true. Resolvers declare how to make it true. The runtime connects them automatically.

import { createModule, createSystem, t } from "@directive-run/core";

const userModule = createModule("user", {
  schema: {
    facts: {
      userId: t.string().nullable(),
      profile: t.object<{ name: string }>().nullable(),
    },
    derivations: {},
    events: { login: { userId: t.string() } },
    requirements: { FETCH_PROFILE: { userId: t.string() } },
  },

  init: (facts) => {
    facts.userId = null;
    facts.profile = null;
  },

  events: {
    login: (facts, payload) => {
      facts.userId = payload.userId;
    },
  },

  constraints: {
    needsProfile: {
      when: (facts) => facts.userId !== null && facts.profile === null,
      require: (facts) => ({ type: "FETCH_PROFILE", userId: facts.userId! }),
    },
  },

  resolvers: {
    fetchProfile: {
      requirement: "FETCH_PROFILE",
      retry: { attempts: 3, backoff: "exponential" },
      resolve: async (req, context) => {
        const res = await fetch(`/api/users/${req.userId}`);
        context.facts.profile = await res.json();
      },
    },
  },
});

const system = createSystem({ module: userModule });
system.start();

// Dispatching login sets userId, which triggers the constraint,
// which emits the requirement, which the resolver fulfills automatically.
system.events.login({ userId: "u-123" });

Events

Events provide typed imperative actions with payloads. Define them in your schema and handle them with events:

events: {
  addItem: (facts, payload: { name: string; price: number }) => {
    facts.items = [...facts.items, { name: payload.name, price: payload.price }];
  },
  removeItem: (facts, payload: { id: string }) => {
    facts.items = facts.items.filter((i) => i.id !== payload.id);
  },
},

// Typed and autocompleted:
system.events.addItem({ name: "Widget", price: 9.99 });

Framework Adapters

PackageFrameworkReactivity Model
@directive-run/reactReact 18+useSyncExternalStore hooks
@directive-run/vueVue 3+Ref / ShallowRef composables
@directive-run/svelteSvelte 4+Readable stores
@directive-run/solidSolid.js 1+Accessor signals
@directive-run/litLit 3+ReactiveController classes

Subpath Exports

ImportPurpose
@directive-run/coreCore runtime – modules, systems, schema types
@directive-run/core/pluginsLogging, devtools, persistence, observability, circuit breaker
@directive-run/core/testingMock resolvers, fake timers, assertion helpers
@directive-run/core/migrationRedux/Zustand/XState migration helpers
@directive-run/core/workerWeb Worker support
@directive-run/core/adapter-utilsShared utilities for building framework adapters

Why Directive?

  • Declarative over imperative – describe what your system needs, not how to wire it up. Constraints and resolvers replace manual data-fetching orchestration.
  • Auto-tracking over manual subscriptions – derivations detect their own dependencies at runtime. No selector functions, no dependency arrays, no stale closures.
  • Constraint-driven over event-driven – instead of chaining events to coordinate async work, declare constraints that the runtime satisfies automatically with retry, batching, and error boundaries.
  • Framework-agnostic core – one state layer, five framework adapters. Move between React, Vue, Svelte, Solid, and Lit without rewriting your state logic.

Documentation

License

MIT

Keywords

directive

FAQs

Package last updated on 02 Jun 2026

Did you know?

Socket

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.

Install

Related posts