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

@rectsh/rect

v0.8.4

Published

Rect — the state store views embed to sync a view model with the Rect host, plus the Vite plugin (./vite) that compiles a view to a deployable bundle.

Readme

@rectsh/rect

The SDK for building Rect views — small interactive apps that bind to a server-side JSON store and sync every edit. An agent (or a person) issues a view, a human opens it at a capability URL, and both sides see live updates.

A view is an HTML bundle containing its UI code and assets. You can hand-write it, or author it in React with this SDK. The host injects the shared, versioned Rect protocol runtime when it serves the view.

SDK projects can also include rect.agent.md. The Vite plugin publishes its Markdown as the agent instructions for creating and updating the Rect, while rect.view.json's description stays a short explanation of when to use it.

npm i @rectsh/rect
npm i -D vite

Quickstart (React)

// src/main.tsx
import { createRoot } from 'react-dom/client';
import { RectProvider, useRectState, useRectField } from '@rectsh/rect/react';

interface Note {
  title: string;
  body: string;
}

function Editor() {
  const state = useRectState<Note>();
  const [body, setBody] = useRectField<string>('body');

  return (
    <main>
      <h1>{state.title}</h1>
      <textarea value={body ?? ''} onChange={(e) => setBody(e.target.value)} />
    </main>
  );
}

createRoot(document.getElementById('root')!).render(
  <RectProvider fallback={<p>Connecting…</p>}>
    <Editor />
  </RectProvider>,
);
// vite.config.ts
import { defineConfig } from 'vite';
import { rect } from '@rectsh/rect/vite';

export default defineConfig({
  esbuild: { jsx: 'automatic', jsxImportSource: 'react' },
  plugins: [rect()],
});
// rect.view.json — the self-describing spec
{
  "name": "Note",
  "description": "Use when an agent and a person need to draft a shared note.",
  "stateSchema": {
    "type": "object",
    "properties": {
      "title": { "type": "string" },
      "body": { "type": "string" }
    },
    "required": ["title", "body"],
    "additionalProperties": false
  },
  "example": { "title": "Untitled", "body": "" }
}
  • pnpm dev — develop in the browser with HMR against a mock host (see below).
  • pnpm build — compile to a single dist/index.html you upload as a view.

The view contract

A view runs inside a sandboxed iframe with host-owned CSP. This shapes everything you build:

  • Prefer self-contained UI bundles. The host-provided Rect runtime is the one exception. Relative asset URLs work because the host serves the whole dist/. The plugin only fails unsupported URL forms: http:// and //; host CSP/sandbox decide whether runtime https:// loads.
  • Use the host bridge for state. Reads and writes are relayed to the parent host over postMessage; any direct runtime https:// request is governed by the host CSP/sandbox.
  • No same-origin storage. localStorage/cookies are unavailable.
  • ≤ 20 MB compiled.

State & syncing

connect() returns a store. Reads are synchronous; writes apply optimistically, are sent to the host as an RFC 7386 JSON Merge Patch. Committed changes return as granular RFC 6902 JSON Patch operations and are rebased onto local optimistic state.

import { connect } from '@rectsh/rect';

const rect = await connect();
rect.get(); // whole view model
rect.get('items.0.done'); // a path (numeric segments index arrays)
rect.subscribe((state) => render(state));
rect.set('title', 'Hi');
rect.update((draft) => draft.items.push(item));
rect.patch({ completion: { approved: true } });
rect.revision; // optimistic-concurrency token

React (@rectsh/rect/react)

| Hook | Purpose | | --- | --- | | <RectProvider> | Connects and provides the store; gates children until ready. Pass store to inject a mock in tests. | | useRectState<T>() | The whole view model. Re-renders on any change. | | useRectValue(selector, isEqual?) | A derived slice; re-renders only when it changes. | | useRectField<V>(path) | [value, setValue] two-way binding for one path. | | useRectActions<T>() | Stable { set, update, patch } handles. | | useRectDispatch() | Dispatch a named action or one of the narrowly allowlisted host commands. | | useRectAttachments() | Resolve or fetch attachment bytes by durable attachment id. | | useRect() | The raw store (escape hatch). | | useRectRevision() / useRectMeta() | Revision / host metadata. |

To continue an Agent-backed App from inside a View, send a person-facing message through the host:

const dispatch = useRectDispatch();
await dispatch('agent-message', 'Form filled. Start the next step.');

The runtime flushes pending ViewModel edits before forwarding the message, so the Agent reads the values the person just entered. agent-message is a host command, not a named action; standalone Views and local mock hosts return agent_unavailable.

The official App Maker uses a separate platform command after its requestPublish action succeeds:

await dispatch('host-command', { command: 'publish-app-draft' });

This command publishes the host-owned App Maker snapshot without starting an Agent turn. It is reserved for the official App Maker; other Rects must not use it and the host validates the bound App run, instance, revision, and caller.

Attachment credentials are runtime state, not ViewModel state. Read bytes by stable attachment id and keep signed URLs out of effect dependencies and cache keys:

const attachments = useRectAttachments();
const response = await attachments.fetch(attachmentId);

Testing (@rectsh/rect/testing)

import { createMockRect } from '@rectsh/rect/testing';

const rect = createMockRect({ title: 'Draft', body: '' });
render(
  <RectProvider store={rect}>
    <Editor />
  </RectProvider>,
);

Local dev (@rectsh/rect/dev)

Develop in a normal browser with HMR against a mock host — no upload loop. A dev.html harness embeds your view in an iframe and plays the host:

import { createRectDevHost, mountRectDevPanel } from '@rectsh/rect/dev';
import spec from './rect.view.json';

const iframe = document.querySelector('iframe')!;
const host = createRectDevHost({
  iframe,
  initialState: spec.example,
  attachmentUploadEndpoint: '/api/rect/dev/attachments',
});
mountRectDevPanel(host, document.getElementById('panel')!);

The panel lets you push state to the view exactly as an agent's patch_view would, so you can see how your view reacts to live updates. Passing the Vite attachment endpoint also makes useRectAttachmentUpload() support the host-owned picker and trusted drop-event files while populating the local $attachments registry through the same policy checks.

Hand-written views

You don't need a bundler. Any HTML that embeds the spec block and calls the host-provided Rect global works. The vanilla examples under public/rect-js/examples/ load the same versioned runtime for standalone local testing. The npm package is a typed adapter around the host runtime.

Examples

Full React views built with this SDK live in examples/:

Or scaffold a fresh project with npm create rect.

License

MIT