Riftix Console Bridge

Development

Monorepo workflow, ports, build tasks.

Prerequisites

ToolVersion
Node24+
pnpm10.33.2
bun1.3+
dockerany recent (local Postgres)

Dev workflow

# Install all dependencies (from repo root)
pnpm install

# One-time: local database (Postgres in docker on localhost:6178)
pnpm db:up
pnpm db:migrate
pnpm db:seed
cp apps/console/.dev.vars.example apps/console/.dev.vars

# Start everything: builds packages, then starts all dev servers
bun run dev

Turbo builds packages in dependency order, then starts the persistent dev servers in parallel.

The seed creates a superadmin (admin@riftix.test / riftix-dev-password), the Riftix admin organization (all apps + the internal admin app), and an Acme Inc. demo organization. Sign in at http://localhost:6173/login. Invite and password-reset emails are printed to the console dev-server terminal unless RESEND_API_KEY is set in .dev.vars. See SETUP.md at the repo root for the full local + production runbook.

What starts

ServerURLNotes
Snippet dev serverhttp://localhost:6175Serves riftix.js with hot-rebuild via tsdown --watch
demo-clienthttp://localhost:6174Vite + React product page ("billing")
demo-vanillahttp://localhost:6177Plain HTML MPA ("crm")
consolehttp://localhost:6173Shell (TanStack Start on the Cloudflare vite plugin)
docshttp://localhost:6176This Fumadocs site (TanStack Start)
Postgreslocalhost:6178docker compose (pnpm db:up)

Turbo tasks

TaskCommandNotes
buildbun run buildBuilds all packages + apps in dependency order
devbun run devdependsOn: ["^build"], persistent, no cache
typecheckpnpm typecheckRuns tsc --noEmit across all packages
cleanpnpm cleanRemoves dist/, .turbo/, node_modules/.cache

Package structure

console/
├── apps/
│   ├── console/            # Shell (TanStack Start + Better Auth + Drizzle)
│   ├── demo-client/        # Billing product demo (Vite + React)
│   ├── demo-vanilla/       # CRM product demo (plain HTML MPA)
│   └── docs/               # This site (TanStack Start + Fumadocs)
└── packages/
    ├── console-bridge-types/          # Shared protocol types
    ├── console-bridge-host/           # Host transport + React adapter
    ├── console-bridge-snippet/        # IIFE bundle + dev server
    ├── console-bridge-snippet-types/  # window.Riftix TS types
    └── console-bridge-snippet-react/  # React hooks

Snippet dev server

The snippet package ships its own standalone dev server at packages/console-bridge-snippet/scripts/dev-server.mjs.

# Start just the snippet server
cd packages/console-bridge-snippet
node scripts/dev-server.mjs

Endpoints:

RouteDescription
GET /riftix.jsThe IIFE bundle
GET /riftix.js.mapSource map
GET /healthz200 ok once built, 503 building before first build
GET /HTML usage page

Headers on every response:

Access-Control-Allow-Origin: *
Cache-Control: no-store

Environment variables:

VariableDefaultDescription
RIFTIX_SNIPPET_HOST127.0.0.1Bind address
RIFTIX_SNIPPET_PORT6175Port

TypeScript config

All packages extend tsconfig.base.json at the repo root:

{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedIndexedAccess": true,
    "verbatimModuleSyntax": true,
    "allowImportingTsExtensions": true,
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler"
  }
}

Build output

PackageFormatOutput
console-bridge-typesESM + CJS + .d.tsdist/
console-bridge-hostESM + CJS + .d.tsdist/
console-bridge-snippetIIFE (minified)dist/riftix.js
console-bridge-snippet-typesESM + .d.tsdist/
console-bridge-snippet-reactESM + CJS + .d.tsdist/

The snippet bundle inlines @riftix/console-bridge-types (no external deps at runtime).


Vite optimizeDeps note

When using @riftix/console-bridge-host in a Vite host app, exclude both subpaths from pre-bundling to prevent Vite from creating two copies of the React context:

// vite.config.ts
optimizeDeps: {
  exclude: [
    "@riftix/console-bridge-host",
    "@riftix/console-bridge-host/react",
  ],
},

Failing to exclude the /react subpath causes useConsoleHost to read from a different context instance than ConsoleHostProvider, resulting in the error: useConsoleHost must be used inside <ConsoleHostProvider>.

On this page