Migration Guide
Twilio Video narrowed its focus.
Here's why teams are migrating.
Twilio announced a sunset of Programmable Video in early 2024, then reversed that decision in October 2024 — but narrowed its focus to 1:1 customer engagement verticals (telehealth, financial services, retail support). Teams building group conferencing, multi-tenant platforms, or custom RTC workflows are looking for an exit. TomatoRTC covers the core Twilio Video surface area — multi-party rooms, signaling, TURN relay, per-stream recording — on infrastructure you own.
Day one
Full parity for the Twilio Video use case — on infrastructure you own.
No per-minute billing. No vendor lock-in on the media path. You migrate to a platform you control.
Production SFU path — equivalent to Twilio Group Rooms.
Browser-to-browser topology — equivalent to Twilio P2P rooms.
connect / publish / subscribe API surface with similar ergonomics.
First-party, tenant-scoped, short-lived credentials. In-repo, not a third party.
API mapping
Access Token → standard JWT you sign.
No Twilio account credentials. No Twilio SDK dependency on the server. You control the secret; TomatoRTC validates your tokens.
- tenantId required Enforced across all room and admin operations — scopes every call.
- role claim host | participant | observer carried in the token.
- Your secret Sign with any standard JWT library. No Twilio dependency.
// Before: Twilio AccessToken + VideoGrant
const token = new AccessToken(accountSid, keySid, keySecret,
{ identity: 'alice' });
token.addGrant(new VideoGrant({ room: 'my-room' }));
// After: standard JWT signed with your own secret
import jwt from 'jsonwebtoken';
const token = jwt.sign(
{
sub: 'alice',
tenantId: 'my-tenant', // ← required
role: 'participant', // ← host | participant | observer
},
process.env.JWT_SECRET, // ← your secret
{ expiresIn: '1h', audience: 'tomatortc' }
);
res.json({ token });Room creation
Same REST pattern, your server, your topology.
Rooms are created via admin API or auto-created on join. The topology field selects SFU (Group Room equivalent) or mesh (P2P equivalent).
# Before: Twilio REST API
curl -X POST https://video.twilio.com/v1/Rooms \
-u "$ACCOUNT_SID:$AUTH_TOKEN" \
-d "UniqueName=my-room" \
-d "Type=group"
# After: TomatoRTC REST API
curl -X POST https://your-server/api/rooms \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "roomId": "my-room", "tenantId": "my-tenant",
"topology": "sfu" }'
# topology: "sfu" = Group Room | "mesh" = P2P room
# RTC_AUTO_CREATE_ROOMS=true skips explicit creationBrowser SDK
One connect call, native MediaStreamTrack — no Twilio wrapper objects.
TomatoRTC uses native MediaStreamTrack directly. No Twilio SDK dependency on the client. Convenience methods replace low-level track creation.
// Before: twilio-video
import { connect } from 'twilio-video';
const room = await connect(token,
{ name: 'my-room', audio: true, video: true });
await room.localParticipant.publishTrack(localVideoTrack);
// After: @rtc-sdk/client-browser
import { createRtcClient } from '@rtc-sdk/client-browser';
const client = createRtcClient({
signalingUrl: 'wss://your-server',
authToken: token,
displayName: 'Alice',
});
const room = await client.joinRoom('my-room');
await room.publishCamera(); // convenience
await room.publishMicrophone(); // convenience
// or: room.publishTrack(mediaStreamTrack, { kind: 'video' })Event mapping
Every Twilio event has a direct equivalent.
Track attachment is unchanged: videoElement.srcObject = new MediaStream([track])
Track publication
Native MediaStreamTrack — drop the Twilio LocalTrack wrapper.
Twilio's LocalTrack objects are not compatible with TomatoRTC. Use native MediaStreamTrack directly or call convenience methods.
Captures and publishes the default video device. Returns a track handle.
Captures and publishes the default audio device.
Launches getDisplayMedia() and publishes the screenshare track.
Publish any existing MediaStreamTrack. Pass { kind: "video" | "audio" }.
Recording
Synthetic WebM foundation today. Bounded PMG compositor slices alongside it.
TomatoRTC ships recording contracts, VP8/Opus WebM muxing, and an in-process synthetic SFU demo. Live signaling-room worker orchestration is not yet a stock recording path; PMG compositor scenes are a separate bounded output capability.
- Lifecycle API Recording lifecycle contracts and management endpoints exist; stock live-room worker wiring remains hardening work.
- Output proof The recording demo writes per-producer VP8/Opus WebM artifacts from synthetic SFU RTP.
- Composition Bounded batch/live PMG scenes ship separately; a durable room-controlled composed-recording workflow remains future work.
Migration steps
Seven steps from Twilio Video to TomatoRTC.
Stand up TomatoRTC locally
pnpm install && pnpm dev:server:sfu:https — verify at https://localhost:8443/kitchen-sink/ (~15 min)
Swap the token endpoint
Replace AccessToken + VideoGrant with a standard JWT signed with your secret. Pass it to createRtcClient.
Replace the room connect call
twilio-video connect() → createRtcClient().joinRoom(). Update event names per the mapping table.
Replace track publication
room.localParticipant.publishTrack() → room.publishCamera() / publishMicrophone() / publishTrack().
Update participant and track rendering
Participant.tracks map → room.remoteParticipants + trackSubscribed event. Track attachment unchanged.
Migrate recording
Treat live-room recording as an integration project: validate worker wiring, storage, synchronization, and whether bounded PMG scenes fit the output requirement.
Update environment and deploy
Set signalingUrl, JWT_SECRET, TURN credentials, and topology in .env. Deploy via Kubernetes manifests or deploy.cloud.sh.
Known gaps
Honest status of every Twilio Video feature.
Most gaps are engineering priorities, not blockers. Factor mobile and composited recording into your timeline if you depend on them.
Migration SOW
Fixed-scope migration engagement for deadline-driven teams.
For teams migrating from Twilio Video under a deadline, TomatoRTC offers a scoped SOW. Contact sales for scoping: sales@tomatortc.com
Map your Twilio room topology and recording path to TomatoRTC equivalents.
Swap AccessToken generation, validate JWT flow end-to-end.
Event handler migration, track publication, remote participant rendering.
Live worker integration, storage, and bounded PMG compositor fit assessment.
Verify SFU room scale and TURN relay capacity before go-live.
Next steps
Three actions to start your migration.
- 1 Run the kitchen-sink demo locally
Stand up the full platform in minutes — verify signaling, SFU, and TURN work in your environment before committing to the migration.
- 2 Map your event handlers
The event table on slide 6 covers every Twilio Video event you likely use. Estimate the client-side effort.
- 3 Schedule a scoping call
We will scope the migration, confirm gap impact for your use case, and define a fixed-fee SOW if needed.