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

@encapsa-dev/brain

v0.1.3

Published

Composable React knowledge graph visualization with an interactive 3D brain, 2D graph, accessible explorer, and compact dashboard previews.

Readme

@encapsa-dev/brain

Make connected knowledge explorable. Encapsa Brain is an open-source React and TypeScript visualization library for knowledge graphs, AI context, documentation networks, and application dashboards. Use an interactive 3D brain, a lightweight 2D graph, or a keyboard-accessible list with a shared selection and inspection model.

Built by Encapsa AI. Your application supplies the data; the library supplies exploration, not a database, an LLM, or an authorization service.

Interactive demo · npm package · GitHub · Issues

Why Encapsa Brain?

  • A brain you can explore: Drag to orbit, rotate with buttons, zoom, select nodes, inspect details, and follow explicit relationships.
  • Small preview, full explorer: Embed a non-interactive overview with one Expand action, then let your host open a tab, panel, or full explorer.
  • Composable context: Group entities into configurable tiers, collapse regions, and distinguish factual context, procedures, and request observations.
  • Progressive rendering: Explicitly opt into WebGL. Use SVG or the accessible list without installing Three.js or React Three Fiber.
  • A library, not a framework: Framework-independent graph utilities, typed React components, optional Forge adapters, scoped CSS, and no Next.js or Tailwind requirement.
  • Your data stays under your control: No built-in fetching, telemetry, storage, API keys, or AI calls. Pass only data your host has authorized.

Installation

Version 0.1.1 established the corrected library package. The initial 0.1.0 npm artifact accidentally packaged the demo workspace; it should not be used as the integration baseline.

Install the latest published release:

pnpm add @encapsa-dev/brain
# npm install @encapsa-dev/brain

React and React DOM are peers. Import the stylesheet once at your application's global stylesheet boundary.

| Host | 2D/list | Optional 3D peers | | --- | --- | --- | | React 18.3.1 | Supported | @react-three/[email protected] + [email protected] | | React 19.2.4 | Supported | @react-three/[email protected] + [email protected] |

Do not pair Fiber 9 with React 18. The release consumer matrix checks the listed combinations, not every version allowed by peer ranges. ESM-only output targets modern browsers; development and package tooling require Node 22.12+ (Node 24 recommended).

Quick start: a knowledge graph

'use client'

import { BrainExplorer } from '@encapsa-dev/brain'
import type { BrainGraph } from '@encapsa-dev/brain/core'
import '@encapsa-dev/brain/styles.css'

const graph: BrainGraph = {
  schemaVersion: '1',
  scopeKey: 'authorized-workspace-42',
  revision: 'snapshot-1',
  completeness: 'complete',
  nodes: [
    { id: 'site', label: 'Website', kind: 'pack', sourceNamespace: 'cms' },
    { id: 'voice', label: 'Brand voice', kind: 'page', sourceNamespace: 'cms' },
    { id: 'review', label: 'Review procedure', kind: 'skill', sourceNamespace: 'cms' },
  ],
  edges: [
    { id: 'site-voice', source: 'site', target: 'voice', kind: 'contains',
      directed: true, evidence: { origin: 'host-supplied' } },
    { id: 'review-voice', source: 'review', target: 'voice', kind: 'references',
      directed: true, evidence: { origin: 'host-supplied' } },
  ],
}

export function KnowledgePanel() {
  return <BrainExplorer graph={graph} renderer="svg" layout="brain"
    theme="light" style={{ width: '100%', height: 520 }} />
}

The library does not infer relationships from node proximity. Provide edges explicitly, and use completeness: 'partial' when the loaded graph is only a subset.

Sidebar preview and dashboard tab

BrainPreview is designed for a narrow sidebar: no rotation controls, no node interaction, no inspector, and exactly one Expand button. The default SVG renderer avoids allocating another WebGL context beside the full explorer.

'use client'

import { useState } from 'react'
import { BrainExplorer, BrainPreview } from '@encapsa-dev/brain'
import type { BrainGraph } from '@encapsa-dev/brain/core'

export function Dashboard({ graph }: { graph: BrainGraph }) {
  const [view, setView] = useState<'content' | 'brain'>('content')

  return <div style={{ display: 'flex', height: 640 }}>
    <aside style={{ width: 224, padding: 12 }}>
      <BrainPreview graph={graph} theme="light"
        style={{ width: '100%', height: 168 }}
        onExpand={() => setView('brain')}
        expandLabel="Open Brain tab" />
    </aside>
    <section style={{ flex: 1, minWidth: 0, minHeight: 0, display: 'flex', flexDirection: 'column' }}>
      <nav aria-label="Dashboard views">
        <button onClick={() => setView('content')}>Content</button>
        <button onClick={() => setView('brain')}>Brain</button>
      </nav>
      <div style={{ flex: 1, minHeight: 0 }}>
        {view === 'brain'
          ? <BrainExplorer graph={graph} variant="embedded" renderer="svg"
              theme="light" showContextTray={false} defaultNavigatorOpen={false} />
          : <p>Your existing dashboard content</p>}
      </div>
    </section>
  </div>
}

The host owns its tabs and focus management. onExpand does not trigger browser fullscreen or navigate automatically. variant="embedded" fills a height-constrained parent and retains the full explorer on narrow screens; provide min-height: 0 through flex ancestors.

The synthetic /embed demo implements this pattern with Content, Conversation, and Brain tabs. It is a layout example, not an integration with a live customer application.

Opt into interactive 3D

For a React 18 host:

pnpm add [email protected] @react-three/[email protected]

For a React 19 host, use Fiber 9.8.1 instead. Keep the loader function stable and outside render:

const loadWebGLRenderer = () => import('@encapsa-dev/brain/webgl')

<BrainExplorer
  graph={graph}
  renderer="auto"
  layout="brain"
  loadWebGLRenderer={loadWebGLRenderer}
  motion="system"
  nodeSize={{ metric: 'targetTokens', scale: 'sqrt', min: 4, max: 10, unknown: 3 }}
/>

auto without a loader renders SVG. A failed WebGL initialization, context loss, or sustained slow-frame condition falls back to 2D with an explicit retry. This is a rendering fallback, never a retry through a less-restricted data source.

Public entry points

| Import | Purpose | | --- | --- | | @encapsa-dev/brain | React explorer, preview, components, hooks, public types | | @encapsa-dev/brain/core | Framework-independent graph, identity, store, layout, projection, and receipt-matching utilities | | @encapsa-dev/brain/react | Provider, composable React components, hooks | | @encapsa-dev/brain/webgl | Optional Three.js / React Three Fiber renderer | | @encapsa-dev/brain/adapters/forge | Pure Forge DTO converters and presentation preset | | @encapsa-dev/brain/styles.css | Scoped styles and CSS custom properties | | @encapsa-dev/brain/layout-worker | Optional worker module; host owns worker construction |

Neither the package root nor the 2D entry points eagerly imports the 3D renderer. No CommonJS or legacy-browser support is claimed.

Compose your own explorer

import {
  BrainProvider, BrainExplorerShell, BrainToolbar, BrainViewport,
  BrainInspector, BrainTierNavigator, BrainLegend, BrainAccessibleList,
} from '@encapsa-dev/brain/react'

<BrainProvider graph={graph}>
  <BrainExplorerShell variant="embedded" showContextTray={false} theme="light" />
</BrainProvider>

For fully custom layouts, compose BrainViewport, BrainInspector, BrainToolbar, BrainTierNavigator, BrainLegend, and BrainAccessibleList inside a .brain-explorer wrapper. The wrapper supplies CSS tokens; your own layout must give the viewport a nonzero size.

Shared dashboard defaults

Renderer and inspector fixes belong in the package, not in copied dashboard components. Starting in 0.1.3, every provider uses continuous connectors by default in both 2D and 3D. Set edgePattern="declared" only when you explicitly want preset/resolver dashed flags; those WebGL patterns now retain endpoints and use length-aware subdivision rather than large missing sections.

BrainInspector and BrainExplorer accept inspectorOptions. Defaults hide unknown versions, the completeness row, the technical metadata footer, and the directed-path form. Known versions, relationship counts, authorized details, security notices, receipt evidence, and context actions remain available. The path finder is retained, not deleted:

<BrainInspector
  showContextActions={false}
  inspectorOptions={{
    showDirectedPaths: false, // opt in when your graph supports the workflow
    labels: { source: 'Source', sourceEvidence: 'Source field' },
  }}
/>

showUnknownVersion, showCompleteness, and showMetadataFooter can explicitly restore those fields. Source pointers are single-line, expandable on hover or focus, and click-to-copy; failure to access the clipboard is reported honestly. Relationship badges count unique loaded edges, not traversals.

For custom dashboard shells, reuse BrainKindFilters, BrainConnectionPicker, BrainPicker, and BrainCopyField from /react rather than implementing their styling and behavior in each application. BrainKindFilters accepts label and kindLabels; BrainConnectionPicker accepts a label and three option labels. The generic BrainPicker accepts labeled, optionally icon-bearing options and supports keyboard selection. Menus and field popovers stay inside the nearest host dialog or .brain-explorer, including native fullscreen.

Main configuration

| Prop / extension | Behavior | | --- | --- | | graph | Immutable, already-authorized snapshot | | preset | Node/edge styles, configurable tier functions or explicit hierarchy | | renderer, layout | Initial standalone view; use view + onViewChange for ongoing controlled state | | variant="embedded" | Fill parent without automatic miniature UI | | showContextTray={false} | Hide composition UI when the host only needs exploration | | theme | light or dark; override scoped --brain-* variables for your brand | | selectedNodeId, onSelectedNodeChange | Controlled selection | | defaultSelectedNodeId | Initial uncontrolled selection | | expandedGroups, onExpandedGroupsChange | Controlled hierarchy | | filters, onFiltersChange | Loaded-label/ref query, kinds, neighborhood, group | | view, onViewChange | Controlled renderer, layout, quality | | nodeSize | Clamped metric-based radii; missing metrics stay distinct | | onRequestDetails | Lazy host-authorized details, with abort/scope/revision checks | | renderNodeDetails, renderNodeActions | Custom inspector content and actions | | nodeStyleResolver, edgeStyleResolver | Renderer-neutral styling | | edgePattern | continuous by default; declared opts into preset/resolver dash flags | | inspectorOptions | Shared visibility controls and label overrides; directed paths opt in | | layoutAdapter, layoutWorkerFactory | Bounded custom layouts / worker execution | | toolbarStart, toolbarEnd, receiptControls | Host interface slots | | loadingSlot, emptySlot, errorSlot, unsupportedSlot | Replaceable status UI | | motion | system, reduced, or full; auto-rotate is off by default | | onDiagnostic | Optional content-free diagnostics; no built-in telemetry |

The explorer ref exposes focusNode(id), fit(), resetCamera(), and rotate(yawRadians, pitchRadians). Controlled values change only when the host accepts their callbacks.

Graph identity and hierarchy

Use stable, namespaced node IDs. Labels, slugs, and content hashes are not globally unique identities. namespacedId(scopeKey, sourceNamespace, resourceKey) and snapshotId(resourceId, version) are available from /core.

Keep the canonical graph separate from presentation grouping. Hierarchy collapse aggregates loaded members without deleting canonical nodes. Declare whether counts are loaded counts or authoritative totals; an unknown total stays unknown.

Safe details and data loading

BrainDataSource supports loadGraph({ scopeKey, cursor, signal }), optional loadDetails({ scopeKey, nodeId, graphRevision, signal }), and optional revision subscriptions. Invoke store.loadGraph(...) from your host data layer; pass the detail loader as onRequestDetails.

The store treats returned graphs as replacement snapshots. If your API returns incremental pages, merge and validate those pages in the host before supplying a graph. Change revision for each new snapshot and scopeKey whenever the authorization context changes, including an account/site/role boundary.

AuthorizedNodeDetails has scopeKey, graphRevision, nodeId, primitive labeled fields, optional authorizedText, and optional evidence pointers. Text is escaped; the package does not render raw HTML or download remote assets. Authorization/scope errors clear graph data and pending work rather than trying another source.

Set copyable: true on an authorized detail field to use the reusable full-value copy/disclosure control. This is independent of its display label, so hosts do not need conventions such as naming every copyable field “Field.”

Forge, AI context, and RAG interfaces

Use the package as a presentation layer for context Packs, page inventories, Skills, retrieved documents, or explicit agent dependencies. It does not retrieve documents, generate embeddings, execute agents, or infer an LLM's reasoning.

The optional Forge adapter separates:

  • normalizeForgeCatalog: summaries and allowlisted host projections.
  • normalizeForgeResolveResponse: public resolved refs/pages and receipt-level fields.
  • normalizeForgeGenerationReceipt: the narrower public generation receipt, without inventing per-source inclusion/redaction.
  • normalizeForgeInternalReceipt: richer evidence explicitly supplied by a trusted host, not a new public Forge API.

Null token counts remain unknown. A PHI flag does not establish redaction. Historical version mismatches remain unmatched. Receipts do not prove an ordered traversal or per-stage timing; the demo's illustrative pipeline is labeled accordingly.

Accessibility, fullscreen, and limitations

The explorer offers search, keyboard-operated controls, semantic entity lists, relationship navigation, reduced-motion support, and light/dark themes. Native fullscreen is attempted only after activation; unsupported environments receive a clearly labeled expanded overlay with focus restoration.

The 3D renderer uses instanced nodes and batched edges. Large loaded graphs should use collapsed regions and focused neighborhoods; there is no unlimited-scale or all-edges-visible promise. Spatial proximity is a layout, not semantic similarity. Automated accessibility tests are useful regression checks, not certification.

Authorization belongs to the host. Filtering or hiding a node in the browser does not secure it, and even metadata can be sensitive. Do not send unauthorized labels, counts, body text, credentials, or compiled prompts to the viewer.

Development and release

Use Node 24 and pnpm 12.3.4. Run the release check from the repository root:

pnpm release:check

It runs the frozen install, package build, typecheck, lint, unit tests, Chromium setup, packed React/Fiber consumer matrix, demo build and browser tests against a temporary production server. It also inspects the package artifact, release version, registry, and generated files. A failed check stops the release.

For an interactive development preview, run pnpm dev separately after pnpm build:package; stop it before the production build.

The repository root is a private demo workspace. Only packages/brain is published. After the release PR and resulting main CI pass, repeat pnpm release:check from a clean, reviewed main checkout. Then publish with:

pnpm --filter @encapsa-dev/brain publish --access public

The package's prepublishOnly hook repeats the release check during publish; publication proceeds only when it passes. The root's publish guard remains in place. Prepack builds the library and copies the canonical README, CHANGELOG, and existing BSD license into the package. See CONTRIBUTING, DEVELOPMENT, and verification notes.

License and community

BSD-3-Clause, copyright Encapsa, Inc. The existing LICENSE is authoritative.

Have a reproducible bug, integration example, or accessibility improvement? Open an issue with a minimal synthetic graph. Explore Encapsa AI to learn about the team building the library.