Technical architecture
Subscriber app for TMWPIX, the pay-TV streaming service run by Brazilian ISP TMW Telecom — one React Native codebase shipping to iOS, iPadOS and Android, unifying linear channels, on-demand film and series, rental titles, internet radio and a seven-day electronic programme guide behind a single subscriber token.
Product screenshots
Tech stack
Engagement
Technical highlights
Live TV, on-demand film, episodic series and internet radio have almost nothing in common at the transport layer: live channels arrive as a continuously rolling HLS or DASH manifest with no seekable duration, VOD arrives as a finite HLS manifest, and radio is a bare audio stream that has to survive the app going to the background. Rather than build four screens, we built one playback container over react-native-video that resolves to AVPlayer on iOS and ExoPlayer (androidx.media3) on Android, and switches behaviour off a single stream-kind descriptor — seek bar, adaptive-bitrate ladder, audio session category and Widevine DRM session are all derived from it. Lock-screen and background controls come from a single MediaSession the container owns, so radio keeps playing and stays controllable after the app is backgrounded. Adding a new content type became a descriptor change, not a new screen.
An operator catalogue is not a feed — it is the ISP's entire library returned in one shot, and a naive fetch-then-render blocks cold start for as long as the payload takes to parse. The catalogue is instead fetched per category, normalised into a flat local store keyed by stream ID, and rendered through windowed FlatList grids that mount only the rows on screen plus a small overscan buffer. Poster art is fetched lazily with a disk-backed image cache, so scrolling back through a category costs nothing. The catalogue snapshot persists locally and is revalidated in the background, which means the second launch renders from cache before the network answers.
The programme guide is the hardest surface in any TV app: a grid where channels run down one axis and time runs across the other, every cell is variable-width because programmes have variable duration, and both axes have to scroll in lockstep with a pinned header and a pinned channel column. Feeding it is a dedicated EPG endpoint returning every channel’s schedule across the window in one JSON payload, large enough that normalising it naively on the JS thread would visibly stall the UI. We fold it into a time-indexed structure keyed by channel, lay cells out by computed offset rather than by flow, and virtualise horizontally as well as vertically so the number of mounted views stays bounded no matter how far the user scrolls into next week. No native module — it ships identically on both platforms.
Access model
TMWPIX is a closed subscriber client, not an open player: it ships with no content, no catalogue and no playlist of its own. TMW Telecom sells the service on tiered monthly plans — each plan carrying its own channel count and a concurrent-stream allowance of two to four screens — alongside per-title rentals for new releases. The app authenticates with a subscriber token, and every channel, category, rental window and guide entry is resolved at runtime from the operator’s endpoint against that subscriber’s entitlement, with multiple household profiles under one account. Rental purchases, profile management and playback telemetry each hit their own endpoint on the operator’s API, and protected titles play back under Widevine. Entitlement, concurrency and licensing all live on the operator side; the app is the delivery surface.
We're happy to go deeper on any architecture decision, share anonymised code samples, or walk through our engineering approach on a call.
Start a conversation →