jChat LogojChat Docs
Addon Development

Addon Architecture & Sandboxing

Architectural overview of JChat's direct runtime execution model, developer sandbox, and schema-scoped boundaries.

Overview

JChat Addons are modular, high-performance packages designed to extend chat functionality—such as custom room widgets, interactive polls, bots, games, and third-party integrations—without modifying JChat Core source code or altering core database schemas.

Addon Development & Runtime Execution Architecture
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                              1. DEVELOPMENT & PACKAGING                                │
│                                                                                        │
│  ┌───────────────────────┐       ┌───────────────────────┐       ┌──────────────────┐  │
│  │   Addon Source Code   │  ──▶  │   Developer Sandbox   │  ──▶ │  Package & Sign  │  │
│  │  Workspace & UI logic │       │  Free disposable mock │       │  SHA-256 digest  │  │
│  └───────────────────────┘       └───────────────────────┘       └────────┬─────────┘  │
└───────────────────────────────────────────────────────────────────────────┼────────────┘
                                                                            │
                                                       Verified Install ────┘
                                                                            │
                                                                            ▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                              2. DIRECT PRODUCTION RUNTIME                              │
│                                                                                        │
│              ┌─────────────────────────────────────────────────────────┐               │
│              │                 Self-Hosted JChat Core                  │               │
│              └────────────────────────────┬────────────────────────────┘               │
│                                           │                                            │
│                     ┌─────────────────────┴─────────────────────┐                      │
│                     ▼                                           ▼                      │
│  ┌─────────────────────────────────────┐     ┌──────────────────────────────────────┐  │
│  │      Direct Frontend (Browser)      │     │        Backend Server Runtime        │  │
│  │                                     │     │                                      │  │
│  │  • Dynamic ESM Stream (React.lazy)  │     │  • Lifecycle Supervision             │  │
│  │  • Host Slot & Error Boundary       │     │  • Scoped Routes: /api/v1/addons/*   │  │
│  │  • Shared QueryClient Cache         │     │  • Session & Permission Guards       │  │
│  └─────────────────────────────────────┘     └──────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────────────────────────────────┘
  1. Production Runtime: Addons execute directly within the host application's browser realm and backend process for maximum speed, native UI responsiveness, and shared cache efficiency.
  2. Developer Sandbox: A disposable, free development edition of JChat where developers can build, live-reload, and test addons without purchasing a commercial license or risking customer data.

Production Runtime Architecture

JChat avoids slow iframes and inter-process RPC brokers. Instead, addons operate as trusted plugins that hook into well-defined host contracts:

1. Direct Frontend Runtime

When a user opens a chat room with active addons:

  • Dynamic ESM Streaming: The host fetches the addon's bundle URL from the active-addon registry and dynamically loads the ESM module via React.lazy.
  • Slot Boundary Hierarchy: The addon's default React component is rendered inside host-managed context providers:
    • <AddonProvider>: Injects room context, active site metadata, theme variables, and SDK utilities.
    • <AddonErrorBoundary>: Catches addon render errors locally and displays a fallback UI, preventing an addon bug from crashing the main chat room.
  • Shared Query Cache: The component directly inherits the host's @tanstack/react-query QueryClient. Addons can fetch, cache, and invalidate queries without instantiating redundant providers.

2. Backend Server Runtime

Addon backend logic is packaged as a modular server component:

  • Server Context: The server bundle exports a router factory receiving AddonServerContext with scoped database access, caching, and real-time utilities.
  • Mount Point Scoping: Core mounts addon API endpoints strictly below the namespaced path:
    /api/v1/addons/:addonId/*
  • Session & Permission Guards: JChat automatically verifies user authentication, active site tenancy, and role-based permissions (requirePermission) before requests reach addon route handlers.
  • Orderly Lifecycle: Installing, updating, or toggling an addon takes effect cleanly with automatic route registration and state management.

Database Boundary & Scoping

Addons require persistent storage, but are strictly isolated from JChat's core application tables (such as users, rooms, messages, or site settings).

PostgreSQL Instance
├── "public" Schema (Core JChat Application Tables)
│    ├── users
│    ├── rooms
│    ├── messages
│    └── site_settings
│
└── "addons" Schema (Isolated Extension Tables)
     ├── pollwise_polls
     ├── glimpse_stories
     └── djdrop_tracks

The Isolated "addons" Schema

  • Dedicated Namespace: All addon tables are placed inside PostgreSQL's shared "addons" schema (e.g., "addons"."pollwise_polls"). This cleanly isolates extension data from core application tables and ensures compatibility across cloud database providers.
  • Mandatory Table Prefixing: To prevent collisions inside the shared "addons" schema, every addon table must use lowercase snake_case prefixed with its addon identifier (e.g., <addonId>_<entity>).
  • Zero Bundle Overhead: Inside AddonServerContext.db, addons interact with the database using a typed query builder facade configured for the "addons" schema. Database interfaces in src/db.ts compile down to 0 runtime JavaScript bytes in the server bundle.
  • Automatic Casing Mapping: The query layer allows addon developers to write idiomatic TypeScript camelCase properties (siteId, createdAt) while automatically mapping to PostgreSQL snake_case columns (site_id, created_at).
  • Verified SQL Migrations: Addon migrations are stored as plain SQL files (migrations/001_initial.sql). JChat validates all migration statements to ensure schema qualification and prohibit unauthorized operations prior to execution.

Host Externals & Zero Bundle Bloat

To keep extension package sizes tiny (typically under 50 KB), common dependencies are marked external during Vite builds and provided by the JChat host application at runtime:

PackageProvided ByPurpose
react & react-domHost Browser EnvironmentComponent rendering & React hooks
@tanstack/react-queryHost React TreeShared server-state query caching & invalidation
@jchat/addon-sdkHost Runtime / SDKType definitions, client hooks, and API client
@jchat/iconHost BundleShared SVG icon pack matching JChat host styling
kyselyHost Server ProcessType-safe SQL query building for the "addons" schema

Real-Time WebSocket Event Bus

Addons broadcast and listen to real-time events across connected room participants and multi-node clusters using the host Redis pub/sub gateway.

Canonical Event Namespacing

To avoid collision between different extensions, all addon events must adhere to the three-part canonical format:

addon:<addonId>:<eventName>

Example Usage:

// Client-side subscription:
useAddonSubscription("addon:pollwise:voteCast", (data) => {
  console.log("New vote recorded:", data.optionId)
})

// Server-side broadcast:
ctx.realtime.broadcastToRoom(roomId, "addon:pollwise:voteCast", {
  pollId: "018f2...",
  optionId: 2,
  totalVotes: 48
})

The Developer Sandbox

To allow third-party developers to build and test extensions without needing a paid JChat commercial license or a production database, JChat provides the Addon Developer Sandbox:

The developer sandbox runs as an isolated, lightweight local environment:

  • No Production License Needed: Pre-configured for local extension development and testing.
  • Local Stack: Spawns isolated PostgreSQL, Redis, and application services on loopback (127.0.0.1).
  • Workspace Mount: Mounts your local addon workspace into the container with hot-reloading.
  • Diagnostic Explorer: Dedicated web dashboard to inspect mounted routes, active slots, and log output.
# Start the sandbox for your addon:
bun addons:sandbox ./addons/my-addon

Trust Model & Verification

Because production addons run in-process for peak performance, JChat enforces security through a verification pipeline:

1. Verified Publisher Signatures
     ↓
2. Bundle Checksum Integrity Verification
     ↓
3. Compatibility Contract Checks (jchat: "^1.0.0", addonSdk: "^1.0.0")
     ↓
4. Site Owner Installation Review & Capability Consent
     ↓
5. Schema Scoping & Permission Guard Verification
  • Publisher Verification: Addons distributed through the official marketplace are verified and cryptographically signed.
  • Integrity Validation: The host verifies immutable bundle checksums before loading any extension code.
  • Rollback & Revocation: If an addon behaves errantly, site administrators can disable or roll back the extension instantly with one click from the Admin Console.

On this page