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

@specverse/runtime

v4.1.14

Published

SpecVerse runtime — view engine, React adapter, Tailwind renderer

Readme

@specverse/runtime

Runtime view engine for SpecVerse — renders spec-driven and dev views at runtime in the browser.

Architecture

@specverse/runtime
  src/runtime/views/
    core/                          Framework-agnostic
    ├── entity-display.ts           Entity name resolution (name > title > label > FK chain > ID)
    ├── field-classification.ts     Field categorization (business, metadata, auto, relationship)
    ├── pattern-engine.ts           View type → pattern detection, CURVED protocol mapping
    ├── composite-pattern-types.ts  9 interfaces for tech-independent view patterns
    ├── composite-patterns.ts       4 pattern definitions (form, list, detail, dashboard)
    ├── atomic-components-registry.ts  49 component type definitions
    └── types.ts                    RuntimeViewProviderValue contract

    react/                         React adapter
    ├── context.ts                  RuntimeViewProvider + useRuntimeContext()
    ├── react-pattern-adapter.tsx   1743-line pattern → HTML renderer
    ├── hooks/
    │   ├── useTheme.ts             Dark/light toggle with localStorage
    │   ├── useResizableSidebar.ts  Draggable sidebar width
    │   ├── useEntityHelpers.ts     Field separation, relationship resolution
    │   └── useEventStream.ts       WebSocket event streaming
    └── components/
        ├── DevShell.tsx            Main dev GUI (tabs: Views, Models, Events)
        ├── ViewRouter.tsx          Sidebar + routing (display, forms, operations)
        ├── RuntimeView.tsx         Pattern-based view renderer
        ├── FormView.tsx            View-spec adapter → ModelManager
        ├── ModelSelector.tsx       Model browser sidebar
        ├── ModelManager.tsx        Full CRUD + lifecycle transitions
        ├── ViewSidebar.tsx         View selection sidebar
        ├── RelationshipField.tsx   Smart FK dropdowns (belongsTo/hasMany/hasOne)
        ├── FieldInput.tsx          Type-aware input (bool, number, datetime, etc.)
        ├── EntitySelect.tsx        Entity dropdown with cascading filters
        ├── OperationView.tsx       Service operation header + executor
        ├── OperationExecutor.tsx   Parameter inputs, execute, result display
        ├── OperationResultView.tsx Formatted results with entity name resolution
        ├── EventStream.tsx         Real-time event log with type filtering
        └── ui/
            └── ResizeHandle.tsx    Draggable resize handle

    tailwind/                      Styling
    └── universal-adapter.ts        48 component types → Tailwind HTML markup

Subpath Exports

// Core utilities (framework-agnostic)
import { getEntityDisplayName, classifyFields, detectPattern, COMPOSITE_VIEW_PATTERNS } from '@specverse/runtime/views';

// React adapter (hooks, components)
import { DevShell, RuntimeView, ViewRouter, FormView, ModelManager, useTheme, useEventStream } from '@specverse/runtime/views/react';

// Tailwind markup generator
import { createUniversalTailwindAdapter } from '@specverse/runtime/views/tailwind';

How It Works

The RuntimeViewProvider Pattern

The runtime package's components are decoupled from any specific state management or API client. Instead, they consume data and hooks through a React context:

// Generated App.tsx (or app-demo's RuntimeBridge)
import { RuntimeViewProvider } from '@specverse/runtime/views/react';

<RuntimeViewProvider value={{
  // Instance-specific hooks — how to fetch data
  useEntitiesQuery: (controller, model) => useMyApiHook(controller, model),
  useModelSchemaQuery: (model) => useMySchemaHook(model),
  useExecuteOperationMutation: () => useMyMutation(),
  useTransitionStateMutation: () => useMyTransitionMutation(),

  // Current state
  entities: { Order: [...], Customer: [...] },
  modelSchemas: { Order: { attributes: {...}, relationships: {...} } },
  views: [...],
  spec: parsedSpec,
  apiBaseUrl: '/api',
}}>
  <DevShell />
</RuntimeViewProvider>

Components call useRuntimeContext() to access this — no direct imports of appStore, API clients, or framework-specific state.

Two Realize Modes

# Runtime mode (default) — slim frontend, views rendered at runtime
specverse realize all specs/main.specly

# Static mode — full frontend, all views pre-generated as code
specverse realize all specs/main.specly --static

Runtime mode generates ~12 frontend files:

  • App.tsx — imports DevShell, sets up RuntimeViewProvider
  • apiClient.ts, useApi.ts, api.ts — instance-specific API wiring
  • dev.specly — auto-generated dev GUI views
  • Config files (vite, tsconfig, package.json, tailwind, postcss)

Static mode generates ~185 frontend files:

  • Per-model view components (list, detail, form, dashboard)
  • Per-model hooks, types, forms
  • Full pattern adapter and tailwind adapter bundled

dev.specly — The Dev GUI Specification

Inference automatically generates dev.specly alongside the inferred spec. It describes the development GUI:

metadata:
  name: MyApp-dev
  type: development
  generated: true

navigation:
  sidebar:
    General:
      - Customer
      - Product
    Customer:
      - Order
    Services:
      - ShippingService

views:
  # Standard views for every model
  CustomerList:
    type: list
    model: Customer

  CustomerDetail:
    type: detail
    model: Customer

  CustomerForm:
    type: form
    model: Customer

  # Specialist views (auto-detected from model characteristics)
  OrderBoard:              # lifecycle → board view
    type: board
    model: Order

  OrderTimeline:           # date fields → timeline view
    type: timeline
    model: Order

  ProductDashboard:        # numeric fields → dashboard
    type: dashboard
    model: Product

  # Service operations
  ShippingService_calculateShipping:
    type: operation
    service: ShippingService
    operation: calculateShipping
    parameters:
      orderId: UUID
      weight: Decimal
    returns: Decimal
    source: service

View Promotion Path

Users can progressively promote dev views to spec views:

1. Dev view (automatic)     — generated in dev.specly, rendered by DevShell
   ↓
2. Named spec view          — copy to main.specly, same rendering
   ↓
3. Configured spec view     — add columns, sort, filters
   ↓
4. Custom spec view         — add full uiComponents, user-owned code

Each step is additive. The runtime engine handles all levels.

How to Use

In a Generated Project (realize)

specverse init my-app --demo
cd my-app
specverse realize all specs/main.specly
cd generated/code
npm run setup
npm run dev:backend   # Start Fastify + Prisma
npm run dev:frontend  # Start Vite dev server → DevShell

The frontend opens with three tabs:

  • Views — browse all spec and dev views
  • Models — CRUD any model, manage lifecycle states
  • Events — real-time event stream from the backend

In app-demo (RuntimeBridge)

// main.tsx
import { RuntimeBridge } from './providers/RuntimeBridge';

<QueryProvider>
  <ApiInitializer>
    <RuntimeBridge>
      <App />
    </RuntimeBridge>
  </ApiInitializer>
</QueryProvider>

Then import components from the runtime package:

import { ViewRouter, FormView, OperationView, usePatternAdapter } from '@specverse/runtime/views/react';
import { ModelSelector } from '@specverse/runtime/views/react';

Standalone Usage

import { RuntimeViewProvider, DevShell } from '@specverse/runtime/views/react';

function App() {
  return (
    <RuntimeViewProvider value={myRuntimeConfig}>
      <DevShell
        devSpec={parsedDevSpec}
        appSpec={parsedAppSpec}
        title="My App"
      />
    </RuntimeViewProvider>
  );
}

How to Extend

Add a New View Type

  1. Add pattern detection in core/pattern-engine.ts:
const VIEW_TYPE_TO_PATTERN = {
  // ... existing
  'kanban': { patternId: 'kanban-view', category: 'data-display' },
};
  1. Add rendering in react/react-pattern-adapter.tsx (or the built-in renderer in RuntimeView.tsx):
if (pattern.patternId === 'kanban-view') {
  return this.renderKanbanView(context);
}
  1. Add to dev.specly generator in engines/src/inference/dev-specly-generator.ts:
if (someModelCharacteristic) {
  views[`${modelName}Kanban`] = { type: 'kanban', model: modelName };
}

Add a New DevShell Tab

Edit runtime/src/runtime/views/react/components/DevShell.tsx:

type TabId = 'views' | 'models' | 'events' | 'mytab';

const TABS: Tab[] = [
  // ... existing
  { id: 'mytab', label: 'My Tab' },
];

// In render:
{activeTab === 'mytab' && <MyComponent />}

Or pass a custom tab via props (not yet implemented — would need a tabs prop on DevShell).

Add a New Tailwind Component

Edit runtime/src/runtime/views/tailwind/universal-adapter.ts:

case 'kanban-column':
  return `
    <div class="bg-gray-100 dark:bg-gray-800 rounded-lg p-4 min-w-[280px]">
      <h3 class="font-semibold text-sm mb-3">${properties.title}</h3>
      <div class="space-y-2">${children}</div>
    </div>
  `;

Create a Framework Adapter (Vue, Svelte, etc.)

The core layer (@specverse/runtime/views) is framework-agnostic. To create a Vue adapter:

  1. Create runtime/src/runtime/views/vue/ directory
  2. Implement the same component set (DevShell, ViewRouter, etc.) using Vue
  3. Use the same core utilities (entity-display, field-classification, pattern-engine)
  4. Add a subpath export: @specverse/runtime/views/vue

The core does the thinking (pattern detection, field classification, entity resolution). The adapter does the rendering.

Bridge to a Custom State Manager

The RuntimeViewProviderValue interface is the only contract. Implement it with any state manager:

// Redux
const value: RuntimeViewProviderValue = {
  useEntitiesQuery: (ctrl, model) => useSelector(state => state.entities[model]),
  entities: store.getState().entities,
  // ...
};

// MobX
const value: RuntimeViewProviderValue = {
  useEntitiesQuery: (ctrl, model) => ({ data: entityStore.get(model), isLoading: false, error: null }),
  entities: entityStore.all,
  // ...
};

Package Dependencies

@specverse/runtime
  ├── @specverse/types (workspace dependency)
  ├── react (peer dependency, ^18.0.0 || ^19.0.0)
  └── react-dom (peer dependency, ^18.0.0 || ^19.0.0)

No other runtime dependencies. The tailwind adapter generates HTML strings — Tailwind CSS is a dev dependency of the consuming project, not of the runtime package.

Known Limitations (v4.1.x)

  • Board, timeline, calendar views — not yet rendered (filtered from sidebar)
  • Service operation routes — generated Fastify backend has no service endpoints
  • Custom controller operations — only standard CRUD routes generated
  • WebSocket events — generated backend has no /ws endpoint (Events tab won't connect)
  • Entity format — handles both flat (Prisma) and wrapped (app-demo) but FK naming varies (camelCase vs snake_case)
  • No tests — runtime components have no unit test coverage

See TODO.md for the full roadmap including the planned backend runtime engine extraction.

Relationship to Other Packages

@specverse/types      Contracts (both build-time and runtime)
@specverse/entities   Language definition (build-time only)
@specverse/engines    Toolchain — parser, inference, realize (build-time only)
@specverse/runtime    View engine (runtime, browser)         ← this package

The engines package knows about runtime (the slim factory generates code that imports it). The runtime package does not know about engines — it only depends on types.