# Mux Video assets, uploads and webhook synchronization - Package: @bijectionhq/mux - Category: Media - Status: Preview - License: Not specified - Bijection source (repository access required): https://github.com/bijectionhq/mux/tree/cf453d509931cb1edc05b142ab7eac023bbc349b - Upstream: https://github.com/muxinc/mux-convex-component/tree/76828f86f68c3416f6953ce5adba40e6cf92579a - Documentation: https://docs.bijection.com/components/using - Directory: https://bijection.com/components/mux ## Get the source Bijection repository access is required. Request access at https://bijection.com/contact. ```sh git clone https://github.com/bijectionhq/mux.git cd mux git checkout cf453d509931cb1edc05b142ab7eac023bbc349b ``` ## Before using this component Read the package README at the recorded revision for setup, dependencies, and API examples. Upstream documentation describes the original package and may differ from the Bijection adaptation. This is a source candidate for evaluation. Catalog inclusion does not establish npm availability or runtime qualification. Check compatibility with your SDK and deployment before adoption. External providers run their own compute. ## Upstream package documentation Recorded 2026-10-23. This describes @mux/convex; check the Bijection adaptation separately. The Mux Convex component synchronizes video data from Mux's video platform into your Convex database, providing real-time updates through webhooks and backfill operations. It creates tables for assets, uploads, live streams, and events, along with mutations and query helpers for managing video catalogs. The component handles the complex integration between Mux's API and Convex's reactive database, keeping your app's video state automatically synchronized. ### Use cases • **Building a video-first application** where you need real-time updates when video processing completes, thumbnails are generated, or live streams change status • **Creating a video content management system** that requires querying video assets by metadata like user ownership, titles, tags, or custom fields • **Developing a video platform** where multiple users upload content and you need to track upload progress, processing status, and asset availability in real-time • **Integrating Mux video into an existing Convex app** without manually managing webhook endpoints, database schema, or API synchronization logic • **Building reactive video UIs** that automatically update when video assets change state, eliminating the need for polling Mux's API ### How it works The component provides Convex tables that mirror Mux's data model, including `assets`, `uploads`, `liveStreams`, and `events`, plus a `videoMetadata` table for app-specific data like user ownership and custom fields. It includes mutations to upsert and delete synced Mux objects, along with query helpers for retrieving video catalog data. Integration happens through two mechanisms: a one-time backfill operation via `migrations:backfillMux` that syncs existing Mux data, and webhook handling through generated routes that process real-time updates. The companion CLI package `@mux/convex-mux-init` scaffolds the necessary app-level Convex files including webhook handlers, HTTP routes, and migration functions. The component follows Convex's architecture pattern where the component itself contains only the schema and database functions, while Node.js runtime code (Mux SDK calls, webhook verification) lives in generated app-level files. This separation allows the component to work within Convex's execution model while still integrating with Mux's Node.js SDK and webhook system. ### Upstream README # Mux Convex Component A reusable [Convex](https://convex.dev) component for apps that use [Mux](https://mux.com) for video. Sync your Mux video data with Convex and build video apps with a real-time database backing your catalog. This package gives you: - Convex tables for Mux `assets`, `uploads`, `liveStreams`, and `events` - Mutations to upsert/delete synced Mux objects - App-level `videoMetadata` storage (`userId`, title, visibility, tags, custom fields) - Query helpers for catalog and user-facing video data - A separate companion CLI package, `@mux/convex-mux-init`, to scaffold app-level Convex wrappers (`npx convex-mux-init`) ## Quickstart ### 1) Install packages ```sh npm i @mux/convex @mux/mux-node npm i -D @mux/convex-mux-init ``` If you prefer not to install the scaffold CLI, you can run it directly with `npx`: ```sh npx @mux/convex-mux-init@latest --component-name mux ``` ### 2) Generate app-level Convex files ```sh npx convex-mux-init --component-name mux # or without installing it npx @mux/convex-mux-init@latest --component-name mux ``` This creates: - `convex/convex.config.ts` - `convex/migrations.ts` - `convex/muxWebhook.ts` - `convex/muxHttp.ts` - `convex/http.ts` if your app does not already have one If files already exist, the CLI skips them unless you pass `--force`. Existing `convex/http.ts` is never overwritten. ### 3) Set Mux API env vars in Convex ```sh npx convex env set MUX_TOKEN_ID npx convex env set MUX_TOKEN_SECRET ``` ### 4) Start Convex and run backfill ```sh npx convex dev npx convex run migrations:backfillMux '{}' ``` ### 5) Register the webhook route If `npx convex-mux-init` created `convex/http.ts` for you, this is already done. If your app already had `convex/http.ts`, wire the generated helper into your existing router: ```ts import { httpRouter } from "convex/server"; import { registerMuxHttpRoutes } from "./muxHttp"; const http = httpRouter(); registerMuxHttpRoutes(http); export default http; ``` ### 6) Configure Mux webhook endpoint In the [Mux dashboard](https://dashboard.mux.com), create a webhook endpoint: - URL for deployed app: `https://.convex.site/mux/webhook` - URL for local development: use a tunnel (e.g. ngrok or cloudflared) to `/mux/webhook` Copy the webhook signing secret and set it in Convex: ```sh npx convex env set MUX_WEBHOOK_SECRET ``` ### 7) Verify data in Convex dashboard Tables to check: - `assets` - `uploads` - `liveStreams` - `events` - `videoMetadata` ## Why both backfill and webhook? - **Backfill** is a one-time catch-up for existing Mux objects. - **Webhooks** keep your Convex tables updated in near real time as Mux state changes. Without webhooks, data will drift over time. ## Runtime model This follows Convex component best practices: - `@mux/convex` is component-only (schema, queries, mutations) - Node runtime integration (Mux SDK, webhook verification, backfill) lives in app-level code in your project - `@mux/convex-mux-init` is the separate CLI package that scaffolds those app-level files for you ## Using a different component name If you mount with a different name, for example: ```ts app.use(mux, { name: "videoInfra" }); ``` Then regenerate wrappers with the matching name: ```sh npx convex-mux-init --component-name videoInfra --force ``` ## Common commands ```sh # regenerate wrappers npx convex-mux-init --component-name mux --force # run backfill with options npx convex run migrations:backfillMux '{"maxAssets":500,"defaultUserId":"dev-user-1","includeVideoMetadata":true}' # run against prod deployment npx convex run --prod migrations:backfillMux '{"maxAssets":500}' ``` ## Troubleshooting - **`Could not find function for 'migrations:backfillMux'`**: Ensure `convex/migrations.ts` exists and exports `backfillMux`, then run `npx convex dev`. - **`InvalidReference ... does not export [mux_node.backfillAssets]`**: Do not call `components..mux_node.*` directly. Use the app-level wrappers generated by `npx convex-mux-init`. - **TypeScript `webhooks.unwrap ... Record`**: Regenerate wrappers with `npx convex-mux-init --force`. - **TypeScript `request.headers.entries is not a function/property`**: Build headers with `request.headers.forEach(...)` in `convex/muxHttp.ts`. - **Webhooks route compiles but never updates tables**: If `ingestMuxWebhook` is generated as `internalAction`, call it via `internal.muxWebhook.ingestMuxWebhook` (not `anyApi.*`). - **`Node APIs without "use node"`**: Ensure Node runtime files start with `"use node";`. - **Bundling fails on `node:fs` / `node:path` from `@mux/convex/bin/*`**: Upgrade to the split packages and use `@mux/convex-mux-init` as the separate scaffold CLI.