convex-mux-component
v0.1.11
Published
Convex Component for syncing Mux video data and app metadata.
Downloads
662
Readme
Mux Convex Component

Yo!
We made a reusable Convex component for apps that use Mux for video and Convex for backend data. We hear from devs and want to make it easier for you to build video apps with a database. Think about it, if you want to build the next TikTok, Instagram, or YouTube, you can use this component to get you started or even migrate your existing data from Mux to Convex and go from there!
This package gives you:
- Convex tables for Mux
assets,uploads,liveStreams, andevents - Mutations to upsert/delete synced Mux objects
- App-level
videoMetadatastorage (userId, title, visibility, tags, custom fields) - Query helpers for catalog and user-facing video data
Packages
- Component package:
convex-mux-component - App scaffolder package:
convex-mux-init
Quickstart
1) Install packages
npm i convex-mux-component convex-mux-init @mux/mux-node2) Generate app-level Convex files
npx convex-mux-init --component-name muxThis creates:
convex/convex.config.tsconvex/migrations.tsconvex/muxWebhook.tsconvex/http.ts
If files already exist, the CLI skips them unless you pass --force.
3) Set Mux API env vars in Convex
npx convex env set MUX_TOKEN_ID <your_mux_token_id>
npx convex env set MUX_TOKEN_SECRET <your_mux_token_secret>4) Start Convex and run backfill
npx convex dev
npx convex run migrations:backfillMux '{}'5) Configure Mux webhook endpoint
In Mux dashboard, create a webhook endpoint:
- URL for deployed app:
https://<your-deployment>.convex.site/mux/webhook - URL for local-only app: use ngrok/cloudflared tunnel to
/mux/webhook
Copy the webhook signing secret and set it in Convex:
npx convex env set MUX_WEBHOOK_SECRET <your_mux_webhook_secret>6) Verify data in Convex dashboard
Tables to check:
assetsuploadsliveStreamseventsvideoMetadata
Why Both Backfill and Webhook?
- Backfill is 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 is intentional and follows Convex component best practices:
convex-mux-componentis component-only (schema, queries, mutations)- Node runtime integration (Mux SDK, webhook verify, backfill) is app-level code in your project
convex-mux-initscaffolds those app-level files
If You Use a Different Component Name
If you mount with a different name, for example:
app.use(mux, { name: "videoInfra" });then regenerate wrappers with matching name:
npx convex-mux-init --component-name videoInfra --forceCommon Commands
# 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}'Agent Checklist
Use this order when automating setup:
npm i convex-mux-component convex-mux-init @mux/mux-node- Run
npx convex-mux-init --component-name <mounted_name> --force - Ensure
convex/convex.config.tsmountsconvex-mux-component/convex.config.jswith the same<mounted_name> - Ensure
convex/http.tsroutesPOST /mux/webhooktointernal.muxWebhook.ingestMuxWebhook - Set
MUX_TOKEN_IDandMUX_TOKEN_SECRET - Run
npx convex dev - Run
npx convex run migrations:backfillMux '{}' - Configure Mux webhook URL and set
MUX_WEBHOOK_SECRET
Troubleshooting
Could not find function for 'migrations:backfillMux': Ensureconvex/migrations.tsexists, exportsbackfillMux, then runnpx convex dev.InvalidReference ... does not export [mux_node.backfillAssets]: Do not callcomponents.<name>.mux_node.*; use app-level wrappers fromconvex-mux-init.TypeScript ... webhooks.unwrap ... Record<string, unknown>: Regenerate wrappers with--forceusing latestconvex-mux-init; expected cast isas unknown as Record<string, unknown>.TypeScript ... request.headers.entries is not a function/property: Build headers withrequest.headers.forEach(...)inconvex/http.ts.- Webhooks route compiles but never updates tables: If
ingestMuxWebhookis generated asinternalAction, call it viainternal.muxWebhook.ingestMuxWebhook(notanyApi.*). Node APIs without "use node": Ensure Node runtime files start with"use node";.
