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

monism

v1.0.25

Published

A theory or doctrine that denies the existence of a distinction or duality in a particular sphere, such as that between interface and implementation, or Design and the runtime.

Downloads

50

Readme

Monism

Monism is a metaphysical stance claiming that everything is ultimately one substance, with apparent dualities (like mind/body, idea/object, interface/class) being modes or expressions of that one underlying unity.


📦 What is the monism package?

monism is a minimal JavaScript toolkit inspired by Spinoza's metaphysical monism, where:

  • Interfaces = Ideas (or Cogitatas)
  • Classes = Bodies (or Individuums)
  • Thought and Extension become design-time and runtime
  • You stop pretending there's a true split between API and implementation

😯 What does it do?

It lets you compose design (interfaces, shared traits, conceptual contracts) and runtime (class implementations) seamlessly using mixins, while honoring both as modes of a unified structure.

It's an alternative to TypeScript in pure JavaScript, but even better.


Duality: Clear Separation

In the world of monism, there are two worlds or realms: the world of thought where ideas are made by Cogis; and the "material" Existentia - the objective world, where Indis come from. Indis need bodies to operate, so they acquire it through Compo, who produces structures, but the first argument to Compo is the Universal of the idea that is to be materialised.


Ideas

In the thought-realm, ideas are made. It doesn't matter what the output of methods are, because ideas are never executed - they are only used as reference for IDE documentation. With monism, it's very much possible to write standard JavaScript classes that act like interfaces by enriching the developer with type information when he's implementing methods internally.

Primitive (Abstract) Idea

/**@abstract*/class BoCherishable extends Boolean {
 /** Whether is cherishable. */
 get cherishable() {return false}
}

/**@abstract*/class NuMagnitude extends Number {
 /** Returns the numeric magnitude. */
 get magnitude() {return 0}
}

/**@abstract*/class StDescription extends String {
 /** Returns the textual description. */
 get description() {return ''}
}

The main three primitive forms of thought are usually boolean, number, and string, but any global object type is available in the JavaScript runtime. The prefix in name of the class is there to indicate the type of fields during debugging, and is by convention 2 symbols in length.

Date types

By returning a new instance of the custom type in the getter, we include additional knowledge about the type in it's metadata. If the name of the object is already present, the convention is to just keep the {Modifier}Name class name:

/**@abstract*/class TempDate extends Date {
 /** Returns the time representation. */
 get tempDate() {return new TempDate()}
}

The above, when the field is accessed via tempDate, from where it is available, it will be seen that it is a temp date, rather than just date (by its constructor type).

/**@abstract*/class DaDate extends Date {
 /**What the date of the entity is.*/
 get date(){return new DaDate()}
}
// ...show more
/**@abstract*/class StartDate extends Date {
 /** Returns when the entity starts. */
 get startDate() {return new StartDate}
}
/**@abstract*/class EndDate extends Date {
 /** Returns when the entity ends. */
 get endDate() {return new EndDate}
}
/**@abstract*/class DaCreatedAt extends Date {
 /** Returns when the entity was created. */
 get createdAt() {return new DaCreatedAt}
}
/**@abstract*/class DaUpdatedAt extends Date {
 /** Returns when the entity was last updated. */
 get updatedAt() {return new DaUpdatedAt}
}
/**@abstract*/class DaValidFrom extends Date {
 /** Returns when the entity becomes valid. */
 get validFrom() {return new DaValidFrom}
}
/**@abstract*/class DaValidUntil extends Date {
 /** Returns when the entity expires. */
 get validUntil() {return new DaValidUntil}
}
/**@abstract*/class DaScheduledAt extends Date {
 /** Returns when the entity is scheduled for. */
 get scheduledAt() {return new DaScheduledAt}
}
/**@abstract*/class DueDate extends Date {
 /** Returns the due date for the entity. */
 get dueDate() {return new DueDate}
}
/**@abstract*/class DaOccurredAt extends Date {
 /** Returns when the event occurred. */
 get occurredAt() {return new DaOccurredAt}
}
/**@abstract*/class EffectiveDate extends Date {
 /** Returns the effective date in business terms. */
 get effectiveDate() {return new EffectiveDate}
}

The dates always start with D as their type. Assignment to dates can be done via their declared field, even if their universal is not called that.

Bags and Associative types

/**@abstract*/class ArItems extends Array {
 /** Returns the list of items. */
 get items() {return []}
}

/**@abstract*/class SeTags extends Set {
 /** Returns the set of unique tags. */
 get tags() {return new Set()}
}

The above provide ordered and un-ordered collections of items. The map, or assiciative array can be stored under <entries> field for example:

/**@abstract*/class MaAttributes extends Map {
 /** Returns the mapping of attributes to their values. */
 get attributes() {return new Map()}
}

There's no need to think too much over the name of the class, it should be named the same as the method with 2-letter code before them to indicate type.

Caching

/**@abstract*/
class WeMaAssociations extends WeakMap {
 /** Returns a new WeakMap representing weak
  *  associations between keys and values.*/
 get associations() {return new WeakMap()}
}

/**@abstract*/
class WeSeTrackedReferences extends WeakSet {
 /** Returns the set of references tracked for
  *  identity uniqueness.                   */
 get trackedReferences() {return new WeakSet()}
}

The weak-entities are cleared with garbage-collection passes and so there's no size operator on caching maps/sets.

Globals

/**@abstract*/class BiInIntegral extends BigInt {
 /** Returns the integral value. */
 get integral() {return 0n}
}

/**@abstract*/class ErError extends Error {
 /** The error stored. */
 get error() {return new Error}
}

/**@abstract*/class ReExTagPattern extends RegExp {
 /** Returns the regex pattern string. */
 get tagPattern() {return /<(tag1|tag2).*?\/?\s*>/}
}

Binary buffers

/**
 * Buffer for NodeJS only.
 * @abstract
 */
class StreamBuffer extends Buffer {
 /** Returns the binary buffer accumulated
  * by the stream so far. */
 get streamBuffer() {Buffer.alloc(0)}
}

In browser:

/**@abstract*/
class U8Binary extends Uint8Array {
 /** Returns the raw binary buffer. */
 get bufferData() {return new Uint8Array()}
}

Any even primitive idea should have declared the inner single key, so that it can be set from inside methods, even if it is not anticipated at front.


These primitive or abstract ideas are foundational — they do not exist independently, but serve as qualities or building blocks for more complex ideas. A "complex idea" might be a combination of several /**@abstract*/ones, e.g., dry, cherishable, red — forming the composed concept of a dry cherishable red umbrella.

Due to JavaScript’s lack of multiple inheritance, complex ideas cannot be created by subclassing multiple /**@abstract*/types (e.g., class DateArray extends Date, Array is invalid). Instead, such combinations must use composition.

The Monism library provides compositional primitives and interface utilities (called universals) that behave almost like native language constructs. These help developers construct compound ideas in a way that's idiomatic, extensible, and clear.

Record Idea

Sometimes, an idea can contain a set of properties, without extending the Object idea.


Universalia

Universals are made by Universalia. They are single-keyed {<field_name>: Idea} metadata objects targeted for monism operators (in particular, Cogi and Compo) to operate on (during runtime) and for type-inference (during devtime).

They expose the interface to the internal idea via a field (or a property). Theoretically, the property can be defined at the time of the use of unviersalia in-line, but because those props against ideas are almost always (95%) reused, the pattern is to pregenerate a universals against the common key that would correspond to the field used to store the value in memory, as seen below.

// src/onto/Cherishable.mjs

import { Universalia } from "@monism/monism"

export var UCherishable=Universalia({cherishable:BCherishable})

This allows to keep ontological models neat: the concepts directly inherit the available global types like Boolean, Number, String; but the reference to them is what is important. The universals produced by Universalia, are pre-declared field on the idea prototype with a particular field (e.g., in {cherishable:BCherishable} case, the field is obviously cherishable).

This allows to compose simple concepts declaratively, without multiplying interfaces that embed those concepts by hand. Sometimes though, the description might need to be adjusted for a certain concept, which can be done in the idea's constructor (when done with Cogi).

Cogitata

Cogi is the complex type of idea where multiple simpler ideas like Universals are composed together lineraly. Because universals directly cannot be inherited more than once, it is required to use monism's runtime capability to simplify the creation of complex ideas using the Cogitata macro.

// src/class/CP/ICP.mjs
import { Cogitata } from "@monism/monism"
import { CAP, UAP } from "./AP.mjs"
import { CBP, UBP } from "./BP.mjs"

/** Idea == Object Public Interface, or
 *  contract visible to other ideas */
class ICP extends Cogitata(UAP,UBP) {
 /** Reports the number of visitors.*/
 get visitorCount() { return 0 }
 /** @param {string} s unique visitor name
  * @return total count of visitors today*/
 async countVisitor(s) {return 0}
}

// Universal
export var UCP=Universalia({cp:ICP})

This simulates composition of universals into a concrete idea, that can be used for structures to materialise.

Material World

Those ideas can be published in the separate package, known as @project/api - they don't actually have the codes to run the program that executes them. They can be used by the @project/lib package that imports those ideas, and based on them, creates compositions, via causas, causas-suis and existentias.

CausaSui

Causa-Sui or Suis are self-causes, meaning they will self-cause a property on the idea by the argument received from the Causal (the thing that causes). This allows to configure the initial state of the structure's conditioning.

import { CausaSui } from "@monism/monism"

export var CherishableS=CausaSui(/**@param{Object}deto
 @param{string}[deto.cherishable] Whether is cherishable. */({cherishable})=>UCherishable)

Sue is a special trait that will read the item from the deto (determinants, options passed at construction time), and if it corresponds to the universal with which it was declared in code (see above), then the intial state of the indi will have that property set to the value from the determinants.

Compositio

Compo brings the ideas into the real world by producing structure. Complex ideas can always be embodied by compo by giving it a universal, some causes, and self-causes; private fields can also be added here for inner reference.

// src/class/CP/_CP.mjs
import { CBP } from "../BP/BP.mjs" // cause of bp
import { CAP } from "../AP/AP.mjs" // cause of ap
import { Compositio } from "@monism/monism"
import { CherisableS } from "../../onto/Cherishable.mjs"

// Structure: Universal (always)
//            + N causes + N self-causes
//            + constructor(deto) {}
//            + private methods and fields
export class _CP extends Compositio(UCP,
 CAP,CBP,
 CherisableS,
 ) {
 /**
  * @param {Object} deto
  * @param {string} [deto.s] Optional example
  */
 constructor({s}) {}

 _countVisitor(s) {return 0}
 get _visitors() {return new Set}
}

Structures need to be exported so that methods found in indi's implemenentation files can reference it (see below) to access its argument types where options might be encoded.

Individuum

Finally, the individuum takes in the structure and adds existentia, i.e., methods which are bound to his this at the runtime.

// src/class/CP/CP.mjs
import { Individuum } from '@monism/monism'
import _CP from './_CP.mjs'
import countVisitor from './methods/countVisitor.mjs'

// Indi: made of structure + implementation
export class CP extends Individuum(_CP,{
 // Existentia - allows to offload methods
 countVisitor:countVisitor, // public

 get visitorCount() {
  var{_visitors}=this
  return _visitors.size()
 }
 // intellisense is accessible on args
 _countVisitor(s) {
  var{_visitors}=this
  _visitors.add(s)
  return _visitors.size()
 }
}) {}

This means methods can be defined using the following:

// src/class/CP/methods/countVisitor.mjs

/**
 * Sanity-checks the argument which should be {string} visitor name
 * @type {import('monism').Method<import('../_CP.mjs')._CP,'countVisitor'>}
 */
export function countVisitor(s) {
 if(s==null||s.length==0) return this.visitorCount
 var{
  cp:{_countVisitor},
  //  ^ the method is auto-bound
 }=this
 return _countVisitor(s)
}

IndividuumCausans

IndiCa is more advanced because it takes the constructor as the second argument, allowing to perform a compute job on itself when starting.

// IndiCa: made of structure + constr + existentia
export class CP extends IndividuumCausans(_CP,({testField})=>{
 return {
  testField:testField?true:false,
 }
},{
 // SAME EXISTENTIA
}) {}

It allows to synchronise some start-up initialisation operations, or provide self-cuase inline, without needing to create a special class of self-cause specially for the individuum.


Declarative Operations

The aim of @monism/monism is to expand the common notion of dull, grey OOP-world with more agentic environment, which is more suitable as the space for program-designers to inhabit; this is done by using compositional principles where the concept of inheritance is phazed out - embracing purely compositional patterns.

This means, that the traditional method-hiding and "polymorphism" need to be rethought at the simulation-level. It is possible to achieve the perks of "inheritance" via composition, if to know what they are, when conceived in the larger scope of things.

Folding

Allows to deny causes to individuums by rewiwring their references to the dependencies to the upper-individuum.

Potentians

Re-binds the entire method to the prototype of the individuum, changing the essence of the individuum through one of its parts.


Chat

💬 Monism Telegram Group

todo

  • [ ] Potentially could offload method loading until the method is invoked, given it could be done with import() statement, could help to avoid power spikes when loading the entire system.

License & Copyright