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

@ixo/editor

v6.2.0

Published

A custom BlockNote editor wrapper for IXO team

Readme

@ixo/editor

A collaborative, workflow editor for the IXO ecosystem, built on BlockNote. Beyond rich text, @ixo/editor turns a document into a runnable flow: blocks carry configuration, conditional logic, and executable actions, execution is gated by a flow engine and authorized with UCAN capabilities, and every change is synchronized in real time across collaborators over the Matrix protocol via Yjs CRDTs.

Internal package. Maintained for IXO products (primarily impacts-x-web). It is published publicly but is not intended as a general-purpose editor. The public API changes with product needs.


What it is

The editor operates in two modes, selected by a document's docType:

  • Template mode (docType: 'template') — design time. Authors configure reusable workflow blocks: properties, conditional logic, dependencies, and which actor may execute what.
  • Flow mode (docType: 'flow', the default) — run time. Participants execute the configured workflow. Conditions are evaluated live, blocks show/hide/enable accordingly, actions run through the flow engine, and per-block runtime state syncs to every collaborator.

Under the hood it combines:

  • BlockNote 0.29 + a custom IXO block schema (checkbox, form, list, proposal, claim, bid, action, notify, domain, …).
  • Yjs CRDTs over Matrix (@ixo/matrix-crdt) for conflict-free, multi-user, persistent state — no separate database required.
  • A flow engine that runs blocks through an activation → authorization → invocation → action → storage pipeline.
  • An action registry of pluggable action types (qi/<namespace>.<verb>) that the generic action block dispatches to.
  • UCAN delegations and invocations for cryptographic, per-block execution authorization.
  • A flow compiler that reads/writes a portable "Base UCAN" flow representation, and a flow agent runtime for automated flow progression.

For the full picture, start with docs/architecture/architecture-overview.md and the plain-language docs/authorization/flows-actions-ucans-explained.md.

Features

  • 🧩 Workflow blocks — checkboxes, forms, lists, proposals, claims, bids, API requests, notifications, domain/entity actions, and a generic action block.
  • 🔀 Template vs flow modes — design reusable workflows, then execute them.
  • 🤝 Real-time collaboration — Matrix + Yjs CRDTs; state is collaborative and persistent by default.
  • ⚙️ Flow engine — declarative activation conditions, actor authorization, and per-block runtime state.
  • 🔐 UCAN authorization — flow owners delegate execution capabilities; invocations provide an auditable trail.
  • 🧠 Action registry — add new action types declaratively; the host app supplies the side-effecting handlers.
  • 🖥️ Server-friendly core@ixo/editor/core exposes the flow engine, action registry, UCAN, and flow agent with no React/Mantine/BlockNote UI dependencies.
  • 🎨 Mantine UI — themable light/dark, self-contained CSS bundles.
  • 🎯 TypeScript-first — augmented editor types and exported prop schemas.

Installation

pnpm add @ixo/editor
# or: npm install @ixo/editor / yarn add @ixo/editor

Peer dependencies

| Package | Version | Needed for | | --------------------------------------------------- | ---------- | ------------------------------ | | react, react-dom | ^18.0.0 | Everything | | @mantine/core, @mantine/hooks, @mantine/dates | ^7.11.2 | The editor UI | | @ixo/matrix-crdt | * | Collaborative editing | | @ixo/surveys | ^0.1.0 | Form / survey blocks | | matrix-js-sdk | >=37.5.0 | Collaborative editing (Matrix) |

v6 is Mantine-only. The Shadcn UI variant that shipped in v2 has been removed. See Migration.

Package entry points

| Import | Contents | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | @ixo/editor | Default entry — the Mantine editor plus the full public API (hooks, components, flow engine, UCAN, flow compiler, flow agent). | | @ixo/editor/mantine | Explicit Mantine entry (same UI surface). | | @ixo/editor/core | UI-free flow engine, action registry, UCAN, flow compiler, and flow agent. Safe for Node/server consumers (e.g. oracles). |

CSS bundles

| Stylesheet | Contents | | ------------------------------- | -------------------------------------------------------------- | | @ixo/editor/style.css | Complete bundle: Inter fonts + Mantine + IXO styles (default). | | @ixo/editor/style-mantine.css | Same as style.css. | | @ixo/editor/style-scoped.css | Scoped variant to reduce global bleed. | | @ixo/editor/style-core.css | IXO custom styles only (advanced/bring-your-own base). |

Quick start (standalone)

A non-collaborative, single-user editor:

import { MantineProvider } from '@mantine/core';
import { useCreateIxoEditor, IxoEditor } from '@ixo/editor';
import '@ixo/editor/style.css';

function MyEditor() {
  const editor = useCreateIxoEditor({
    theme: 'light',
    initialContent: [
      { type: 'heading', content: 'Welcome to the IXO Editor', props: { level: 1 } },
      { type: 'paragraph', content: 'Type “/” to insert a block.' },
    ],
  });

  return (
    <MantineProvider>
      <IxoEditor editor={editor} onChange={() => console.log('changed')} />
    </MantineProvider>
  );
}

Collaborative editing

Real-time, multi-user editing backed by a Matrix room. useCreateCollaborativeIxoEditor builds the Y.Doc, wires the MatrixProvider, and returns the editor alongside the live CRDT handles.

import { MantineProvider } from '@mantine/core';
import { useCreateCollaborativeIxoEditor, IxoEditor } from '@ixo/editor';
import '@ixo/editor/style.css';

function CollaborativeEditor({ matrixClient }) {
  const { editor, connectionStatus, connectedUsers, awarenessInstance } = useCreateCollaborativeIxoEditor({
    theme: 'light',
    roomId: '!roomId:matrix.org',
    matrixClient,
    permissions: { write: true },
    user: {
      id: '@did-ixo-ixo1abc:server', // Matrix user ID
      name: 'Jane Doe',
      color: '#FF5733',
      accessToken: 'matrix-access-token',
      address: 'ixo1abc…', // bech32 address
      did: 'did:ixo:ixo1abc…', // full DID, required for UCAN signing
    },
  });

  return (
    <MantineProvider>
      <div>Connection: {connectionStatus}</div>
      <IxoEditor editor={editor} connectedUsers={connectedUsers} awarenessInstance={awarenessInstance} />
    </MantineProvider>
  );
}

The hook returns { editor, connectionStatus, title, yDoc, root, flowArray, connectedUsers, awarenessInstance }. permissions.write defaults to false (read-only). See docs/architecture/architecture-overview.md for the Y.Doc structure and docs/authorization/matrix-permissions.md for the access model.

Providing handlers

The editor is domain-agnostic: it never imports blockchain, DAO, or API code. The host app injects that behavior as handlers (and optional blockRequirements) on <IxoEditor>. Blocks and action types call into these to fetch data and perform side effects.

<IxoEditor
  editor={editor}
  handlers={{
    getCurrentUser: () => ({ address: wallet.address, name: wallet.name }),
    submitClaim: async (params) => cosmos.submitClaim(params),
    sendNotification: async (params) => api.notify(params),
    // …implement the handlers your blocks/action types require
  }}
  blockRequirements={{ proposal: { coreAddress: dao.coreAddress } }}
/>

The full BlocknoteHandlers surface (proposals, claims, bids, lists, notifications, domain creation, UCAN signing, user search, …) is exported and documented in docs/architecture/architecture-overview.md. For action types specifically, handlers are adapted into ctx.services via buildServicesFromHandlers — see the action registry section and docs/guides/action-block-pattern.md.

useCreateIxoEditor options

| Option | Type | Default | Description | | ------------------- | --------------------------------- | ------------------ | -------------------------------------------- | | theme | 'light' \| 'dark' | 'light' | Editor color theme | | docType | 'template' \| 'flow' | 'flow' | Design vs execution mode (local, not synced) | | initialContent | PartialBlock[] | undefined | Initial editor content | | uploadFile | (file: File) => Promise<string> | Data-URL converter | File upload handler | | editable | boolean | true | Whether the editor is editable | | sideMenu | boolean | true | Show side menu (drag handle, plus button) | | slashMenu | boolean | true | Enable slash command menu | | formattingToolbar | boolean | true | Show formatting toolbar | | linkToolbar | boolean | true | Show link toolbar | | filePanel | boolean | true | Show file panel | | tableHandles | boolean | true | Show table manipulation handles |

useCreateCollaborativeIxoEditor extends these with roomId, matrixClient, user, permissions, and optional docId / title / sourceTemplateId (IxoCollaborativeEditorOptions).

<IxoEditor> props (selected)

| Prop | Type | Description | | --------------------------------------------------- | ---------------------------- | --------------------------------------------- | | editor | IxoEditorType \| undefined | Instance from a create hook | | handlers | BlocknoteHandlers | Host integration callbacks for blocks/actions | | blockRequirements | BlockRequirements | Runtime context data for specific blocks | | translate | Translate | i18n function (t) from the host app | | mantineTheme | MantineTheme | Theme object to apply to the editor subtree | | onChange | () => void | Fired on content change | | onSelectionChange | () => void | Fired on selection change | | connectedUsers / awarenessInstance | see collaborative hook | Enable per-block presence indicators | | className, children, coverImageUrl, logoUrl | — | Layout/customization slots |

See IxoEditorProps in the exported types for the complete list.

Core concepts

Flow engine

@ixo/editor/core (src/core/lib/flowEngine/) runs a block through a four-stage pipeline:

  1. Activation — are upstream dependency conditions satisfied?
  2. Authorization — is the current actor permitted (whitelist or UCAN delegation chain)?
  3. ExecutionexecuteNode(...) orchestrates invocation → action → storage.
  4. Runtime — a Y.Map-backed FlowRuntimeStateManager tracks per-block state (idle/running/completed/failed) and syncs it via CRDT.

Runtime state is the source of truth for a block's result — never mirror it into local React state. This rule is spelled out in CLAUDE.md and docs/architecture/block-runtime-state.md.

Action registry

The generic action block dispatches to a registered action type keyed by a can string (qi/<namespace>.<verb>). Each action type declares its inputs, output schema, and a run() that calls into ctx.services. The host app implements the underlying handlers; buildServicesFromHandlers wires them in. To add one, follow docs/guides/action-block-pattern.md and, for signed actions, docs/guides/slide-to-sign-and-diff-guide.md.

UCAN authorization

Flow owners (flowOwnerDid) issue delegations granting specific actors permission to execute specific blocks; invocations record proof of execution. Both live in dedicated Y.Doc maps and sync with the document. See docs/authorization/ucan-technical.md and docs/authorization/ucan-flow-authorization.md.

Flow compiler & flow agent

The flow compiler (src/core/lib/flowCompiler/) converts between a portable "Base UCAN" flow description and the live Y.Doc (setupFlowFromBaseUcan, readFlowAsBaseUcan, compileBaseUcanFlow, …), enabling flows to be authored, cloned, and merged. The flow agent runtime (src/core/lib/flowAgent/) drives automated progression of a flow (leases, command queue, policy evaluation, ledger) — see docs/flow-engine/.

Custom blocks

The IXO block schema is registered automatically by the create hooks. Blocks can be inserted from the slash menu (/) or programmatically:

editor.insertBlocks([{ type: 'list', props: { title: 'Members', did: 'did:ixo:entity123', fragmentIdentifier: 'members' } }], editor.getTextCursorPosition().block, 'after');

The full block catalog, prop schemas, and conditional-logic system are documented in docs/architecture/architecture-overview.md and docs/architecture/editor-type-map.md.

Server-side usage

Consumers that only need flow logic (e.g. an oracle validating or advancing a flow) can import the UI-free core:

import { executeNode, isAuthorized, createUcanService, compileBaseUcanFlow, tickFlowAgent } from '@ixo/editor/core';

This entry point pulls in no React, Mantine, or BlockNote code.

Documentation

All documentation lives in docs/ and is indexed by docs/README.md. Highlights:

Development

pnpm install          # install dependencies
pnpm build            # build all bundles (tsup → dist/, + CSS)
pnpm run dev          # rebuild on change
pnpm run type-check   # tsc --noEmit
pnpm test             # vitest
pnpm run example:action-gallery   # run the action-type gallery example app

Project structure

editor/
├── src/
│   ├── core/            # UI-free core (flow engine, action registry, UCAN,
│   │   │                #   flow compiler, flow agent, types, GraphQL client)
│   │   └── index.ts     # @ixo/editor/core entry
│   ├── mantine/         # Mantine editor: IxoEditor, hooks, blocks, components, context
│   │   └── index.ts     # @ixo/editor/mantine entry
│   ├── styles/          # Source CSS
│   ├── data/ icons/ images/   # Static assets
│   ├── test-utils/      # Test helpers
│   └── index.ts         # Default entry (Mantine + full public API)
├── docs/                # Documentation (see docs/README.md)
├── examples/            # Example apps & configs (action-type-gallery, …)
├── plans/               # Implementation plans
├── fonts/               # Inter font files
├── dist/                # Build output (generated)
├── style*.css           # Published CSS bundles (generated)
└── package.json

Requirements

  • React 18+ and React DOM 18+
  • Mantine 7 (@mantine/core, @mantine/hooks, @mantine/dates)
  • A modern browser (ES2020+)
  • For collaboration: a Matrix server, matrix-js-sdk, and @ixo/matrix-crdt

Migration

v2 (multi-UI) → v6 (Mantine-only)

The Shadcn UI variant and its @ixo/editor/shadcn / style-shadcn.css entry points have been removed. Use the default or /mantine entry:

// Before (v2)
import { IxoEditor } from '@ixo/editor/shadcn';
import '@ixo/editor/style-shadcn.css';

// Now (v6)
import { IxoEditor, useCreateIxoEditor } from '@ixo/editor';
import '@ixo/editor/style.css';

The editor also evolved from a rich-text wrapper into a full workflow/flow engine — the flow engine, action registry, UCAN authorization, flow compiler, and flow agent are new since v2. See the documentation to adopt them.

Contributing

Internal package. Use Conventional Commits (enforced by commitlint; releases are automated via semantic-release). See CLAUDE.md for project rules and commit format. Record structural repo/doc reorganizations in ORGANIZATION-LOG.md.

License

MIT © IXO Team