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

yopl

v1.2.0

Published

Embeddable Prolog-style logic engine for JavaScript: declarative rules, unification, backtracking search, and four solver drivers (sync/async × callback/generator). Useful for pattern matching with extraction, constraint search, type inference, planners,

Readme

yopl NPM version

yopl is an ES6 mini-library that implements a Prolog-style logic solver in JavaScript. It provides:

  • A small core solver with multiple driver styles: callback, generator, async callback, async generator.
  • A built-in rule library: helpers and control predicates, comparisons, arithmetic, bitwise, and boolean logic.

Its only runtime dependency is deep6, itself a zero-dependency library that provides the unification engine.

What it does and when to use it

yopl lets you describe a problem as a set of rules over JavaScript values and ask the solver to find values that satisfy them. You write declarative rules; the engine handles search, unification, and backtracking. You stay inside JavaScript — there is no embedded DSL to parse, no separate Prolog runtime, and rules can call back into plain JS (sync or async) whenever a piece of logic is easier to express that way.

It is useful when a problem is awkward to express as straight-line code but natural to express as constraints or relations:

  • Pattern matching and shape validation against deeply nested data, where you also want to extract values during the match.
  • Searching configurations, dependency graphs, or rule sets for combinations that satisfy several conditions at once.
  • Type-inference-like or tag-propagation passes over an AST or IR.
  • Small expert systems, planners, permission/policy checks, and "find me an X such that Y" queries embedded inside a larger JS app.
  • Test fixtures and property-style checks that need to enumerate all values matching a spec.

If you only need single-direction pattern matching, a regex or a destructuring assignment is simpler. Reach for yopl when you need bidirectional matching (unification), backtracking across alternative rules, or enumeration of all solutions — and you want all of that without leaving your JavaScript codebase.

Installation

npm install --save yopl

Quick start

import {variable} from 'deep6/env.js';
import assemble from 'deep6/traverse/assemble.js';
import solve from 'yopl';

const rules = {
  member: [(V, X) => [{args: [{value: V, next: X}, V]}], (V, X) => [{args: [{next: X}, V]}, {name: 'member', args: [X, V]}]]
};

const list = {value: 1, next: {value: 2, next: {value: 3, next: null}}};
const X = variable('X');

solve(rules, 'member', [list, X], env => {
  console.log('X =', assemble(X, env));
});
// X = 1
// X = 2
// X = 3

Modules

| Module | Purpose | | -------------------------- | ------------------------------------------------------------------------------- | | yopl (src/solve.js) | Synchronous callback solver — main entry point. | | yopl/solvers/gen.js | Synchronous generator solver. | | yopl/solvers/async.js | Async callback solver. | | yopl/solvers/asyncGen.js | Async generator solver. | | yopl/rules/system.js | Helpers + control predicates (head, term, list, cut, call, not, …). | | yopl/rules/comp.js | Comparisons: lt, le, gt, ge, nz. | | yopl/rules/math.js | Arithmetic: add, sub, mul, div, neg. | | yopl/rules/bits.js | Bitwise: bitAnd, bitOr, bitXor, bitNot. | | yopl/rules/logic.js | Boolean logic: logicalAnd, logicalOr, logicalXor, logicalNot. |

Per-module documentation lives in the wiki.

CommonJS

yopl ships as ESM only. CommonJS consumers can use Node's built-in dynamic import():

const {default: solve} = await import('yopl');

A full CJS interop demo lives in tests/test-cjs.cjs (run it with node tests/test-cjs.cjs).

Development

git clone [email protected]:uhop/yopl.git
cd yopl
npm install
npm test

See CONTRIBUTING.md for the development workflow and AGENTS.md for AI-agent rules.

Release history

  • 1.2.0 — removed CJS build, restructured tests, added TypeScript typings, simplified list creation, bug fixes and performance improvements, expanded docs and wiki.
  • 1.1.4 — updated dependencies.
  • 1.1.3 — updated dependencies.
  • 1.1.2 — updated dependencies.
  • 1.1.1 — updated dependencies.
  • 1.1.0 — deep6 was extracted from this package and is now a dependency.
  • 1.0.1 — added the exports statement.
  • 1.0.0 — first 1.0 release.