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

untitled-bridge

v3.2.0

Published

Plugin-based builder bridge with live design token editing, smart element selection, source tracking, and two-way live editing support

Readme

untitled-bridge

A plugin-based builder bridge SDK that enables live design token editing, element selection, source tracking, and two-way live editing between preview iframes and parent builder applications.

Features

  • 🎨 Live Design Token Editing: Figma-like live CSS variable updates via postMessage
  • 🔌 Plugin Architecture: Extensible message routing with namespaced plugins
  • 🎯 Smart Element Selection: Interactive/content elements only (excludes structural divs)
  • 🔒 Session Tokens: Built-in token validation for secure handshakes
  • 📡 Event Streaming: Hover, click, scroll events with element metadata
  • 🌓 Theme Toggle: Runtime dark/light mode switching
  • 🎯 Source Tracking: Automatic element identification with unique IDs and source file mapping
  • ✏️ Two-Way Live Editing: Inline text and image editing with real-time sync
  • 🖼️ Image Editing: Right-click to edit image sources with instant updates

Element Selection Behavior

Selectable Elements

  • Interactive: a, button, input, textarea, select, form
  • Text: h1, h2, h3, h4, h5, h6, p, span, label, strong, em, li
  • Media: img
  • ARIA: [role="button"]

Excluded Elements

  • Structural/Layout: main, section, div, header, footer, nav, aside, article
  • Meta: html, body, head, script, style, meta, link, title
  • Hidden/tiny elements (width < 1px or height < 1px)

Install (from npm)

npm install untitled-bridge

Use in a web app (Next.js/App Router or Pages Router)

Add a side-effect import at your root entry so it runs on the client:

// app/layout.tsx or pages/_app.tsx
import 'untitled-bridge';

When the page loads in the browser, you'll see:

[untitled-bridge] v3.0.0 - Plugin Architecture Enabled
[untitled-bridge] DesignSync plugin initialized

Live Design Token Editing

The bridge includes a built-in DesignSync plugin that enables Figma-like live editing of CSS variables.

From Parent App: Apply Token Changes

// Send live token update to iframe
iframe.contentWindow?.postMessage({
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "designTokens/applyPatch",
  token: sessionToken,
  patch: {
    "color.primary": { 
      base: "oklch(0.7 0.2 265)",           // Light mode
      modes: { dark: "oklch(0.85 0.15 195)" } // Dark mode
    },
    "color.background": { 
      base: "oklch(1 0 0)" 
    },
    "radius": { 
      base: "0.5rem" 
    }
  }
}, iframeOrigin);

Supported Tokens

| Token Key | CSS Variable | Description | |-----------|--------------|-------------| | color.background | --background | Page background | | color.foreground | --foreground | Main text color | | color.primary | --primary | Primary brand color | | color.primary.fg | --primary-foreground | Text on primary | | color.card.bg | --card | Card background | | color.muted | --muted | Muted background | | color.border | --border | Border color | | color.ring | --ring | Focus ring | | radius | --radius | Border radius |

Toggle Theme Mode

// Switch to dark mode
iframe.contentWindow?.postMessage({
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "ui/setThemeMode",
  token: sessionToken,
  mode: "dark"  // or "light"
}, iframeOrigin);

Request Current Token Snapshot

// Request current CSS variable values (for debugging/inspect)
const requestId = crypto.randomUUID();

iframe.contentWindow?.postMessage({
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "designTokens/requestSnapshot",
  token: sessionToken,
  requestId: requestId
}, iframeOrigin);

// Listen for response
window.addEventListener("message", (e) => {
  if (e.data.type === "designTokens/snapshot" && e.data.requestId === requestId) {
    console.log("Current tokens:", e.data.snapshot);
  }
});

Plugin Architecture

The bridge exposes a global window.UntitledBridge object with plugin registration capabilities.

Creating a Custom Plugin

const myPlugin = {
    init: (ctx) => {
        // Called once when plugin is registered
        // ctx: { post, state, getCssVar, setCssVar }
        console.log("Plugin initialized with token:", ctx.state.token);
    },

    onMessage: (msg, ctx) => {
        // Called when matching namespace message arrives
        // msg.type format: "namespace/action"
        if (msg.type === "myPlugin/doSomething") {
            const currentBg = ctx.getCssVar("--background");
            ctx.setCssVar("--my-custom-var", "red", ":root");
            ctx.post({
                protocol: "untitled-bridge",
                type: "myPlugin/done",
                token: ctx.state.token
            });
        }
    }
};

// Register plugin (matches "myPlugin/*" messages)
window.UntitledBridge.registerPlugin("myPlugin", myPlugin);

Plugin Context API

Plugins receive a context object with:

| Method | Description | |--------|-------------| | post(type, payload) | Send message to parent window | | getCssVar(name) | Read CSS variable from :root | | setCssVar(name, value, scope) | Write CSS variable ( :root or scoped) | | state.token | Current session token | | state.allowedOrigin | Allowed postMessage origin |

CLI

After installing (or via npx once published):

npx untitled-bridge

Prints:

[untitled-bridge] Hello World (CLI)

Local development

# run the module directly
node index.js

# run the CLI directly
node bin/untitled-bridge.js

# or pack a tarball for testing in another app
npm pack
# then in another app
npm install ../untitled-bridge-1.1.0.tgz

Two-Way Live Editing

The bridge now supports seamless two-way editing between visual preview and source code:

Text Editing

  • Click any text element in edit mode to start inline editing
  • Press Enter to save, Escape to cancel
  • Changes are instantly reflected via HMR and saved to source files

Image Editing

  • Right-click any image in edit mode to edit its source URL
  • Changes are applied immediately with instant visual feedback

Source Tracking

  • Each element gets a unique data-ub-id attribute for tracking
  • Source file mapping via data-source-file attributes
  • Enables precise code-to-visual element correlation

Edit Mode Messages

// Enable edit mode
iframe.contentWindow?.postMessage({
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "setEditMode",
  enabled: true
}, iframeOrigin);

// Text edit event
{
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "textEdit",
  ubId: "ub-1234567890-0",
  sourceFile: "src/App.jsx",
  elementSelector: "h1.welcome",
  newText: "Updated heading",
  originalText: "Welcome"
}

// Image edit event
{
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "imageEdit",
  ubId: "ub-1234567890-1",
  sourceFile: "src/App.jsx",
  newSrc: "https://example.com/new-image.jpg",
  originalSrc: "https://example.com/old-image.jpg"
}

Protocol Version

Current: 0.3.0

All messages use the format:

{
  protocol: "untitled-bridge",
  version: "0.3.0",
  type: "namespace/action",
  token: string,
  ...payload
}

Version History

| Version | Changes | |---------|---------| | 3.2.0 | Two-way live editing, source tracking, image editing, enhanced messaging | | 3.1.4 | Plugin architecture, live design token editing, theme toggle | | 2.1.1 | Smart element filtering (exclude divs/sections/main) | | 2.0.0 | Enhanced selection + metadata | | 1.x | Basic bridge + hello handshake |

Notes

  • The package logs on import; keep the import 'untitled-bridge' in a client-executed file.
  • All design token updates apply immediately without page reload
  • Supports both light and dark mode variants via modes in token patches
  • CSS variable scoping uses data-theme attribute for theme switching
  • Set executable bit on the CLI if needed locally: chmod +x bin/untitled-bridge.js