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

@dialtribe/dialtribe-bobl

v2.9.2

Published

Bobl studio — puppet editor, rendering engines, and physics

Readme

@dialtribe/dialtribe-bobl

The complete Bobl puppet studio editor — drop-in React component with all types, rendering engines, physics, hooks, and UI.

External Installation

yarn add @dialtribe/dialtribe-bobl

Publishing to NPM (once installed - see below)

  1. Build first: npm run build
  2. Bump version: npm version patch (or minor/major)
  3. Login (if not) npm login
  • to troubleshoot: npm whoami or run in succession: npm logout npm login npm whoami -> (to confirm it worked)
  1. Publish: npm publish --access restricted
  2. run:
unset NPM_TOKEN  # clears the stale value so the fallback kicks in
bash scripts/sync-clients.sh

Local Development

For developing the package locally without publishing:

0. One time setup

npm install --save-dev typescript
npm install --save-dev @types/react @types/react-dom @types/node
npm run build

NOTE: you may still need to troubleshoot installing certain types

1. Build the package (with watch mode)

cd dialtribe-bobl
npm install
npm run dev

This runs tsc --watch and Tailwind CSS watch in parallel — any change to src/ recompiles to dist/ automatically.

2. Run the demo app

In a separate terminal:

cd dialtribe-bobl/demo
cp .env.example .env    # fill in your dialtribe API URL, app ID, etc.
npm install
npm run dev             # opens on http://localhost:3012

The demo uses "file:.." to link directly to the parent package. Vite picks up changes from dist/ with hot reload — no publishing needed.

3. Test in bobl (or another consumer app)

Instead of publishing, use yarn link:

# In the package root
cd dialtribe-bobl
npm link

# In bobl
cd bobl
npm link @dialtribe/dialtribe-bobl

Changes to src/ (with npm run dev running) are immediately available in bobl. Run npm unlink @dialtribe/dialtribe-bobl in bobl when done to switch back to the published version.


Required peer dependencies

yarn add react react-dom swr livekit-client \
  @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities \
  opentype.js

Optional peer dependencies (install for specific features)

# Face tracking (MediaPipe head/face detection)
yarn add @mediapipe/tasks-vision

# Phone calling (Telnyx VoIP)
yarn add @telnyx/webrtc

# Audio modifiers (pitch shift, robot voice, etc.)
yarn add tone soundtouchjs

# GIF picker in chat panel
yarn add gif-picker-react

Authentication

BoblStudio authenticates API calls using session tokens (sess_...). The full auth flow works as follows:

  1. Your server calls POST /api/public/v1/sessions on the dialtribe API using your secret key (dt_sk_...) to create a scoped session token for the current user.
  2. Your client fetches that token (e.g. via your own /api/session-token route) and passes it to <BoblStudio authToken={token} />.
  3. BoblStudio sends the token as Authorization: Bearer sess_... on every API request.
  4. Sliding expiry: When a session token is used within 30 minutes of its expiry, the server automatically extends it by 1 hour. Active users are never logged out mid-workflow.
  5. Token refresh: Pass onTokenExpiring to automatically refresh the token ~5 minutes before it expires. The callback should return a fresh session token string.

Creating a session token (server-side)

// POST to dialtribe API with your secret key
const res = await fetch(`${DIALTRIBE_API_URL}/api/public/v1/sessions`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${DIALTRIBE_SECRET_KEY}`, // dt_sk_... secret key
  },
  body: JSON.stringify({
    permissions: ["app:read", "app:write", "broadcasts:watch", "broadcasts:write", "content:read", "content:write", "chat:read", "chat:write"],
    user_id: "your-user-123", // optional external user ID
    ttl: 3600, // 1 hour (default), max 86400 (24 hours)
  }),
});

const { session_token, expires_at, permissions } = await res.json();

Available permissions

| Permission | Description | |---|---| | app:read | Read app metadata and configuration | | app:write | Update app settings | | broadcasts:watch | View broadcast metadata and status | | broadcasts:write | Create and manage broadcasts | | content:read | Read content metadata and listings | | content:write | Create, update, delete content | | content:watch | View and play audio/video content | | content:clip | Create clips from existing content | | content:upload | Upload new audio/video content | | content:transcribe | Request transcription of content | | content:summarize | Request AI-generated summaries | | chat:read | Read chat messages and room state | | chat:write | Send chat messages |

Quick Start — Drop-in Editor

The primary export is <BoblStudio /> — a single component that renders the entire puppet studio editor.

Usage Modes

BoblStudio supports three usage modes depending on how it is deployed:

1. Anonymous / Demo mode

No authToken provided. The studio renders the full workspace with local-only state. All API fetches (app data, shows, project persistence, streaming) gracefully return defaults so the editor is fully usable for offline creation. Save-to-server and go-live features are disabled.

"use client";

import { BoblStudio } from "@dialtribe/dialtribe-bobl";

export default function DemoPage() {
  return (
    <BoblStudio
      appId="demo"
      baseUrl="https://api.dialtribe.tv"
    />
  );
}

2. Authenticated partner app (e.g. bobl)

Pass baseUrl, authToken, and onTokenExpiring so API calls reach the dialtribe server with authentication. The authToken is a session token (sess_...) created via the sessions API. All features are enabled including project persistence, streaming, and chat.

"use client";

import { useState, useEffect } from "react";
import { BoblStudio } from "@dialtribe/dialtribe-bobl";

export default function StudioPage() {
  const [authToken, setAuthToken] = useState<string>();

  useEffect(() => {
    fetch("/api/session-token")
      .then((r) => r.ok ? r.json() : null)
      .then((d) => { if (d?.sessionToken) setAuthToken(d.sessionToken); })
      .catch(() => {});
  }, []);

  return (
    <BoblStudio
      appId="Z6fICpr"
      orgSlug="bobl"
      baseUrl={process.env.NEXT_PUBLIC_DIALTRIBE_API_URL}
      authToken={authToken}
      onTokenExpiring={async () => {
        const res = await fetch("/api/session-token");
        const data = await res.json();
        return data.sessionToken;
      }}
      header={<MyAppHeader />}
    />
  );
}

3. Same-origin dialtribe app

When running inside the dialtribe app itself, omit both baseUrl and authToken. All API calls use relative URLs and authenticate via the user's session cookie.

<BoblStudio
  appId={appId}
  orgSlug={orgSlug}
  header={<AppHeader app={app} title="Studio" />}
/>

BoblStudioProps

| Prop | Type | Required | Description | |------|------|----------|-------------| | appId | string | Yes | The app ID (NanoId) to load the studio for | | orgSlug | string | No | Organization slug, used for URL construction | | isPopup | boolean | No | Whether this is rendered in a popup window (defaults to false) | | header | ReactNode | No | Optional header component rendered above the studio (e.g., navigation bar) | | builderUrl | string | No | URL to the puppet workshop/builder page | | baseUrl | string | No | Base URL for all dialtribe API calls (e.g. "http://localhost:3010"). Defaults to "" (relative URLs). Required when running outside the dialtribe app. Omit for same-origin deployment. | | authToken | string | No | Auth token sent as Authorization: Bearer header on all API requests. Accepts a session token (sess_...) or secret API key (dt_sk_...). When omitted in a partner app, the studio operates in anonymous/demo mode with local-only state. | | onTokenExpiring | () => Promise<string> | No | Callback invoked ~5 minutes before the session token expires (assumes 1-hour TTL). Should return a fresh session token string. The studio automatically updates the auth context with the new token. If not provided, the token expires naturally. |

API Base URL

All internal fetch calls (asset uploads, project persistence, stream control, etc.) are prefixed with baseUrl. This is distributed via React context (DialtribeApiContext) so every nested hook and component automatically uses the correct server.

If you need the base URL in custom code, use the context hook:

import { useApiBaseUrl } from "@dialtribe/dialtribe-bobl";

function MyCustomComponent() {
  const apiBase = useApiBaseUrl();
  // apiBase is "" when inside dialtribe, or "http://localhost:3010" in partner apps
  const res = await fetch(`${apiBase}/api/private/...`);
}

For non-React utility functions (e.g. uploadFileToCdn, exportProject), pass baseUrl as an option:

import { uploadFileToCdn } from "@dialtribe/dialtribe-bobl";

await uploadFileToCdn(file, appId, { baseUrl: "http://localhost:3010" });

Next.js Setup

Add to your next.config.ts:

const nextConfig: NextConfig = {
  transpilePackages: ['@dialtribe/dialtribe-bobl'],
};

Example: Full Next.js page

// app/studio/[id]/page.tsx
"use client";

import { useParams } from "next/navigation";
import { BoblStudio } from "@dialtribe/dialtribe-bobl";

export default function StudioPage() {
  const { id } = useParams();

  return (
    <div className="h-screen w-screen">
      <BoblStudio
        appId={id as string}
        orgSlug="my-org"
        baseUrl={process.env.NEXT_PUBLIC_DIALTRIBE_API_URL}
        header={
          <header className="h-14 bg-gray-900 flex items-center px-4">
            <h1 className="text-white font-bold">My Studio</h1>
          </header>
        }
      />
    </div>
  );
}

Using Types & Engines Directly

Everything is importable from the top-level barrel:

import type { Overlay, PuppetStyle, Trigger, Viewport } from "@dialtribe/dialtribe-bobl";
import { OverlayRenderer, PhysicsEngine, createPuppetOverlay } from "@dialtribe/dialtribe-bobl";

Types Reference

stage-overlays — Core overlay & puppet state

| Key Exports | Description | |---|---| | Overlay | Union interface for all canvas elements (text, image, video, puppet, shape, group, etc.) | | OverlayType | "text" \| "image" \| "video" \| "puppet" \| "shape" \| "group" \| "audioVisualizer" \| "spawnPoint" \| "viewport" \| "template" | | TextStyle, ImageStyle, VideoStyle, PuppetStyle, ShapeStyle, GroupStyle | Per-type style interfaces | | OverlayAnimation | Animation config (entrance, exit, looping expressions) | | PhysicsStyle, PhysicsConfig | Physics simulation settings per overlay | | AnchorConstraint | Spatial constraints between overlays (pin, hinge, spring, rail, look-at) | | AnimationPath | Path-based movement (linear, orbital, waypoint, follow) | | FaceLayout | Puppet face feature positioning | | createPuppetOverlay(), createTextOverlay(), createImageOverlay(), etc. | Factory functions for each overlay type | | sortOverlaysForRendering() | Z-index sort for draw order | | PUPPET_Z_INDEX | Default z-index for puppet overlays |

puppet-parts — Body part tree & layers

| Key Exports | Description | |---|---| | PuppetPart | Tree node — has children, layers, jiggle physics, parallax | | PuppetPartType | "body" \| "head" \| "face" \| "eyes" \| "mouth" \| "leftArm" \| "rightArm" etc. (15 types) | | PuppetLayer | Visual layer within a part (asset, opacity, z-index) | | PuppetAsset | Image, SVG, primitive shape, or spritesheet | | FaceSwapRule | Maps face tracking channels to layer variants | | PuppetPose | Named snapshot of part transforms for pose blending | | PuppetOutfit | Collection of layer changes for outfit switching |

triggers — Event-driven actions

| Key Exports | Description | |---|---| | Trigger | A trigger with conditions and actions | | TriggerCondition | Keyboard, timer, media position, API poll, file watch, viewport enter/leave | | TriggerAction | What happens: show/hide/move overlays, play audio, scene transitions | | SceneTransition | Transition effects between scenes (cut, fade, wipe, curtain, etc.) | | createTrigger(), createDefaultAction() | Factory functions |

modifiers — Visual & audio effects

| Key Exports | Description | |---|---| | VisualModifier | Chroma key, blur, color adjust, pixelate, crop, tile, shape mask, etc. | | AudioModifier | Pitch shift, robot, telephone, echo, cave, megaphone | | createVisualModifier(), createAudioModifier() | Factory functions |

viewports — Multi-viewport management

| Key Exports | Description | |---|---| | Viewport | A named rectangular view with position, size, crop, easing | | MAIN_VIEWPORT, MAIN_VIEWPORT_ID | The default viewport | | EasingType | Transition easing between viewport positions |

show-settings — Broadcast configuration

| Key Exports | Description | |---|---| | ShowSettings | Title, guest access, stream formats, resolution, face tracking, waiting room | | CANVAS_SIZE | Reference workspace size ({ width: 1280, height: 1280 }) | | DEFAULT_SHOW_SETTINGS | Sensible defaults | | VideoFrame | Decorative frame graphic for framed video display | | WaitingRoomConfig | Pre-show countdown configuration |

face-tracking — Face tracking & LOD

| Key Exports | Description | |---|---| | FaceTrackingData | MediaPipe face landmark values (mouth, eyes, brows, head rotation, pupils) | | PuppetVideoOverride | Replaces puppet with live video (fill or framed mode) | | LodTier | Level of detail: "full" \| "reduced" \| "placeholder" | | computeLodTier(zoom) | Returns appropriate LOD for a given zoom level |

Additional types

| Module | Key Exports | |---|---| | index (shared) | App, Broadcast, Clip, Upload, Content | | integrations | ShowIntegrationClient, ChatPlatform | | keyboard-shortcuts | Keyboard shortcut definitions | | media-sources | MediaSource, VideoSourceConfig | | power-board | PowerButton, PlaybackMode | | project | ProjectExport, SourceManifestEntry | | scene-group-export | Scene group import/export types | | shared-sources | SharedSource, ParticipantDisplayMode | | show-requests | Show join request types | | streaming | StreamDestinationClient, StreamPlatform | | transcription | TranscriptSegment, TranscriptExportFormat |


Engines

OverlayRenderer

Canvas rendering engine — draws all overlay types onto an HTML canvas.

import { OverlayRenderer } from "@dialtribe/dialtribe-bobl";

const renderer = new OverlayRenderer();
renderer.render(ctx, overlays, canvasWidth, canvasHeight, time);

PhysicsEngine

Spring-based physics for jiggle, bounce, and sway effects.

import { PhysicsEngine } from "@dialtribe/dialtribe-bobl";

const physics = new PhysicsEngine();
const transform = physics.update(overlay, deltaTime, faceData);

Other engines

| Engine | Description | |---|---| | ConstraintSolver | Spatial constraints between overlays (pin, hinge, spring, rail, look-at) | | PathAnimator | Path-based movement (linear, orbital, waypoint, follow) | | EntranceExitEngine | Entrance/exit animation state and transforms | | VisualModifierProcessor | Visual modifier stack processing (chroma key, blur, etc.) | | evaluateFaceSwapRules() | Face-driven layer variant selection | | getPoseTransformForPart() | Pose blending per body part | | applyOutfit() | Outfit layer changes on body-part tree | | flattenPartTree() | Flatten hierarchical body-part tree |


Tracking Hooks

// Face tracking (MediaPipe FaceLandmarker — face, pose, hands)
import { useHeadTracking } from "@dialtribe/dialtribe-bobl";
import type { FaceData, HeadTrackingOptions } from "@dialtribe/dialtribe-bobl";

// Audio analysis (mic level → mouthOpen)
import { useAudioAnalyzer } from "@dialtribe/dialtribe-bobl";
import type { AudioSettings, AudioAnalyzerState } from "@dialtribe/dialtribe-bobl";

// Tracking state consumed by renderBobblehead()
import type { BobbleheadTrackingState } from "@dialtribe/dialtribe-bobl";

Utilities

// Puppet asset library — pre-made SVG assets
import { PUPPET_ASSET_LIBRARY, getAssetsForPart, searchAssets } from "@dialtribe/dialtribe-bobl";

// Puppet defaults — factory functions for body-part trees
import { createDefaultBodyParts, createLimbParts } from "@dialtribe/dialtribe-bobl";

// Workspace coordinate math
import { overlayToWorkspace, percentToPixelX, overlayIntersectsViewport, REFERENCE_SIZE } from "@dialtribe/dialtribe-bobl";

Package Structure

src/
  index.ts                          — barrel export
  BoblStudio.tsx                    — full editor component (<BoblStudio />)
  DialtribeApiContext.ts            — API config context (baseUrl, authToken)
  types/                            — all TypeScript type definitions
    index.ts                        — App, Broadcast, Clip, Upload, Content
    stage-overlays.ts               — Overlay, styles, factory functions
    puppet-parts.ts                 — PuppetPart tree, layers, face-swap, poses
    puppet-appearance.ts            — Legacy simple puppet appearance
    modifiers.ts                    — Visual & audio modifier stack
    triggers.ts                     — Event/action trigger system
    viewports.ts                    — Multi-viewport cameras
    show-settings.ts                — Broadcast & show configuration
    face-tracking.ts                — FaceTrackingData, PuppetVideoOverride, LodTier
    integrations.ts                 — Chat platform integrations
    keyboard-shortcuts.ts           — Shortcut definitions
    media-sources.ts                — Media source configs
    obs-import.ts                   — OBS import result types
    power-board.ts                  — Power board button types
    project.ts                      — Project export/import types
    scene-group-export.ts           — Scene group sharing types
    shared-sources.ts               — Guest shared source types
    show-requests.ts                — Join request types
    streaming.ts                    — Stream destination types
    transcription.ts                — Live transcription types
  engines/                          — rendering & physics engines
    overlay-renderer.ts             — Canvas rendering engine
    physics-engine.ts               — Spring physics simulation
    constraint-solver.ts            — Spatial constraint resolution
    path-animator.ts                — Path-based movement
    entrance-exit-engine.ts         — Entrance/exit animations
    visual-modifier-processor.ts    — Effect stack processing
    face-swap-engine.ts             — Face-driven layer swapping
    pose-engine.ts                  — Pose blending
    outfit-engine.ts                — Outfit switching
    puppet-asset-library.ts         — SVG asset registry
    puppet-defaults.ts              — Body-part tree factories
    workspace-transform.ts          — Coordinate math
  components/                       — React UI components
    puppet-studio/                  — 84 editor panel components
    modifiers/                      — 5 modifier stack UI components
    chat/                           — 5 chat components (GIF picker, reactions, etc.)
  hooks/                            — 45 React hooks
    useOverlays.ts                  — Central overlay state management
    usePuppetWebSocket.ts           — Real-time puppet sync
    useHeadTracking.ts              — MediaPipe face detection
    useModifierStack.ts             — Audio/visual modifier pipeline
    useTriggers.ts                  — Trigger evaluation & execution
    useViewports.ts                 — Viewport state management
    useLiveKitRoom.ts               — LiveKit video room management
    useProjectPersistence.ts        — Auto-save & project loading
    useCrashRecovery.ts             — IndexedDB crash recovery
    ... and 36 more
  lib/                              — utility functions
    asset-upload.ts                 — CDN asset upload
    canvas-thumbnail.ts             — Canvas JPEG capture
    fonts.ts                        — Font registry & Google Fonts loading
    shape-boolean.ts                — Boolean geometry (union, intersect, subtract)
    template-engine.ts              — Template variable binding
    viewport-templates.ts           — Viewport layout presets
    obs-import/                     — OBS scene collection importer
    ... and more