Skip to main content
Build production-ready realtime video integrations. This guide covers camera setup, connection management, prompt strategy, error handling, and mobile-specific considerations.

Camera setup

Always use the model’s built-in constraints when requesting camera access. Each model defines the fps, width, and height it expects — passing these directly avoids scaling artifacts and wasted bandwidth.
Requesting a resolution that doesn’t match the model’s expectations forces the browser to scale the video. This adds latency and can reduce output quality.

Handling constraint failures

Not every device supports every resolution. Use ideal constraints as a fallback when targeting a wide range of hardware:

Front vs back camera

On mobile devices, specify the facingMode to select the camera:
When switching between front and back cameras, recapture the stream — each camera has different hardware capabilities that affect resolution and frame rate.

Front-camera mirroring

For selfie streams, pre-flip the input with mirror. Server-baked pixels (watermarks, overlays) then come out in display orientation, and the output renders as-is.
  • "auto" mirrors when the input track reports facingMode: "user".
  • Pass true when your app already knows the camera is front-facing (desktop webcams often don’t report facingMode).
The SDK only flips the stream it sends — not your local preview.

Connection management

Connect once, update prompts

Establishing a WebRTC connection takes a few hundred milliseconds. Don’t reconnect just to change the style or prompt — use set() or setPrompt() instead:

When to reconnect

Reconnect only when you need to:
  • Switch models (e.g., from Lucy Restyle Live to Lucy 2.1) — each model runs on a different pipeline
  • Switch cameras — the stream changes, so you need a new connection
  • Recover from a failed connection after auto-reconnect gives up

Track connection state

Always listen to connectionChange events to update your UI:
Connection states:

Prompt strategy

Use prompt enhancement

Enable enhance: true (the default) to let Decart expand short prompts into detailed descriptions. This dramatically improves output quality for simple inputs:
Start with enhancement enabled. Only disable it when you need exact control over the prompt text.

Atomic updates with set()

Since set() replaces the entire state, always include every field you want to keep. When using Lucy 2.1 with both a prompt and reference image, include both in every call:

Debounce rapid prompt changes

If your UI lets users type prompts in a text field, debounce the input to avoid sending dozens of rapid updates:

Error handling

Listen for errors

Always register an error handler. Without one, connection failures go unnoticed:

Auto-reconnect

The SDK automatically reconnects when an unexpected disconnection occurs (e.g., network interruption). It retries with exponential backoff up to 5 times:
  1. Connection drops → state moves to "reconnecting"
  2. SDK retries with increasing delays
  3. If reconnection succeeds → state moves back to "generating"
  4. If all retries fail → state moves to "disconnected" and an error event fires
You don’t need to implement reconnection logic yourself — but you should update your UI to reflect the reconnecting state.

Wrap setup in try/catch

Camera access and connection can both fail. Catch errors early:

Cleanup

Always release resources when the session ends or the component unmounts:
Forgetting to call disconnect() leaves WebRTC connections open, consuming bandwidth and server resources. Always clean up.

Client-side authentication

Never expose your permanent API key in client-side code. Use short-lived client tokens instead:
1

Create a backend endpoint

2

Fetch and use the token in the browser

Client tokens only prevent new connections after expiry. Active WebRTC sessions continue working even after the token expires.

Firewall and network configuration

Realtime integrations need outbound access to Decart’s API, signaling, diagnostics, and media endpoints.

Domains to allow

Staging environments use turn.stage-decart.com and api.stage-decart.com instead.

Ports and protocols

UDP restrictions and proxy behavior are the most common causes of “it connects, but the video freezes” issues.

UDP traffic and proxy configuration

  • Allow outbound UDP traffic on port 7882.
  • Allow TURN over UDP on port 3478.
  • Do not force media through an HTTP or HTTPS proxy that cannot pass UDP if you want the lowest-latency path.
  • For SNI or transparent proxies, allow the domains above and do not TLS-intercept turn.decart.ai; decrypting that traffic breaks the connection.

Mobile considerations

React Native / Expo

React Native realtime runs on LiveKit’s React Native stack — plain react-native-webrtc is not supported.
  • Install the LiveKit packages and register globals. registerGlobals() must run before your app/router entrypoint so the SDK can reach WebRTC:
For Expo, add the @livekit/react-native-expo-plugin and @config-plugins/react-native-webrtc config plugins to app.json, then run npx expo prebuild. LiveKit does not run in Expo Go.
  • Select VP8 with preferredVideoCodec. React Native works best with VP8. Set it as an option — the SDK negotiates the codec, so there’s no manual SDP rewriting:
  • Size the camera with resolveFpsNumber. Use the model’s dimensions and resolve its FPS descriptor to a number for native capture:
  • Browser-only features are rejected. mirror, debugQuality, and the deep connectivity preflight fail with UNSUPPORTED_PLATFORM_FEATURE on React Native. Mirror the local preview with LiveKit’s <RTCView mirror> instead.
  • Handle app lifecycle. Disconnect when backgrounded, reconnect when foregrounded:
See the Realtime Mobile App walkthrough for a complete Expo integration with model switching and style presets.

Battery and bandwidth

Realtime WebRTC streaming consumes significant resources on mobile:
  • Disconnect when not visible. Use app lifecycle events to pause streaming in the background.
  • Match camera constraints to model. Don’t request 4K when the model expects 720p — this wastes encoding power and bandwidth.
  • Use front camera when possible. Front cameras typically have lower resolution, which reduces encoding overhead.

Session tracking

Use the generationTick event to track session duration and display billing information to users:

Quick reference

Next steps

Lucy 2.1 Guide

Character transformation with reference images

Reference Image Guide

Best practices for character and style reference images

JavaScript SDK

Full SDK reference for realtime features

Mobile App

Complete Expo walkthrough