AI-Assisted React Native Migration for TV: Lessons From Zattoo

Authors

If you want the full story, the webinar is now available online, with Pavel Verkhovskyi and Bogdan Plieshka from Zattoo walking through the migration in their own words. The visuals in this article are taken from their presentation. If you’d rather read the recap, you’re in the right place.

TV is where cross-platform promises get tested very quickly. You can make a nice diagram with one shared codebase in the middle and a few platforms around it, but the real world of TV apps is messier than that.

There are different operating systems, different generations of devices, different remotes, different input models, different store requirements, different playback stacks, and a very wide range of hardware performance. For streaming apps, the hard parts usually show up even faster. Playback has to be reliable. DRM has to work. Focus handling has to feel natural. The app needs to behave well on devices that may be several years old and still actively used in someone’s living room.

Zattoo was dealing with all of that at scale across its own direct-to-consumer product and a wide set of white-label variants. Those products could differ by branding, country, content catalog, channel lineup, VOD library, configuration, and platform footprint.

For years, the practical way to handle that was native platform development. Android had its own team and codebase. Apple had its own team and codebase. Web-based smart TVs and set-top boxes had their own setup. Desktop web was separate as well. This made sense historically, because ten years ago the cross-platform options for this kind of streaming product were either not available or not mature enough.

The question later became: how long can you keep scaling by adding more platform-specific work?

Native TV apps break down at the org level first

The technical duplication is easy to spot. Every platform needs:

  • the player
  • TV guide
  • content details
  • search
  • settings
  • account flows
  • white-label configuration
  • analytics
  • and all the smaller pieces around them

The organizational duplication is more painful, because it affects every product decision.

Each platform team owns the full app experience inside its ecosystem. When a new feature is designed, it has to travel through several teams, several codebases, and several release processes. Even if everyone agrees on the intended behavior, the final result can still drift slightly because every implementation is separate.

A good example is the pause button in the player.

In a simple app, pause is just pause. In Zattoo’s case, the behavior depends on the country, content type, permissions, and playback path behind the scenes. From the user’s perspective, pressing pause should feel obvious. Inside the product, fixing inconsistent behavior around that single control required people from backend and multiple frontend ecosystems to align on what the button should do.

Nobody starts a migration because of one button, but small examples like this show where the real pressure comes from. The same product behavior has to be understood, implemented, tested, and released several times. The more platforms and white-label variants you add, the more coordination becomes part of the implementation cost.

The push came from Fire TV and Vega

Zattoo had already explored ways to reuse more of their existing work before going deeper into React Native.

PWA-style approaches made sense in some places. WebView-based ideas were also considered. For some targets, especially where the browser environment was a natural fit, this helped. But TV streaming is not only a UI problem. DRM, native playback integration, device APIs, input, performance, and the general “this feels like a TV app” quality all matter.

React Native had been on the radar as well, but adopting it for a product of this size was a bigger decision than trying another UI framework. It would affect architecture, teams, release management, testing, hiring, and long-term platform ownership.

The concrete push came from Amazon.

Zattoo was invited to learn about Amazon’s new operating system, now known as Vega OS, where React Native was presented as the main way to build apps. Fire TV was already important for Zattoo, both for their own product and for white-label partners, so this was not an abstract platform experiment.

They had two paths in front of them:

  • build one more dedicated app for one more platform and continue the same model as before
  • use Vega as the starting point for a broader React Native foundation

They chose to investigate the second path properly.

The first step was a SWOT analysis. Zattoo already had a React-based web ecosystem in a monorepo, with shared configuration, utilities, business logic, and infrastructure. That gave them something to build on. At the same time, they did not yet have React Native engineers in-house, existing apps still needed maintenance, and product roadmaps were already planned.

So the migration started with a much smaller question: can this work for the core TV experience?

Start with proof, not a rewrite

The first proof of concept focused on the parts that could make or break the idea.

Can the user log in? Can the app talk to Zattoo’s backend? Can it play a stream? Does input work? Can the same code run on web, Android, and Vega?

There was no need for the first version to look polished. For a migration like this, a rough prototype is often more useful than a pretty one, because it exposes the uncomfortable questions earlier. Playback, focus management, remote input, platform integration, and build tooling are the areas where optimistic assumptions tend to fail.

The early prototypes showed the same code running across environments, including web, Android, and Vega. For the engineering team, that made React Native much easier to evaluate. Instead of discussing cross-platform development as a strategy slide, they could look at working code and decide which problems were real.

This also helped with internal adoption. The initial effort started small, with a couple of engineers working through the proof of concept. As the results became more concrete, more people joined, and the work grew from an experiment into a team effort.

Shared code works best when platform differences stay visible

The useful part of React Native in this story is not that Zattoo tried to make every TV platform identical.

They did the opposite: they shared the parts that made sense to share and kept platform differences explicit where they mattered.

The existing monorepo helped here. Some pieces were already good candidates for reuse, like configuration, JavaScript utilities, and shared business logic. React Native could become another project inside that ecosystem instead of a completely separate island.

For the application code itself, the important architectural choice was to keep the common path clean. Shared implementations can live in default files, while platform-specific versions can be introduced only where needed. This is much easier to work with than scattering platform checks throughout the codebase.

A TV app has many areas where sharing works well:

  • TV guide
  • content details
  • search
  • shared product logic

Other areas need more care:

  • playback
  • SSO
  • input handling
  • content integrations with the operating system
  • device-specific behavior

This is where React Native fits nicely, as long as the team does not treat “shared” as a religion.

A good shared TV stack should make the common case boring and the platform-specific case obvious. When a platform needs its own implementation, it should be easy to find, review, test, and remove later if it stops being needed.

Performance, testing, and rollout still need platform-specific handling

React Native did not remove the hard parts of TV development for Zattoo. Performance still had to be measured on real devices, especially on Android TV, where fragmentation was far higher than on tvOS or Fire OS. Zattoo’s telemetry showed more than 800 Android TV device types, which meant heavy flows like the TV guide had to be improved from production data, not lab assumptions.

That data had to come from the signals that actually shape the viewing experience: playback quality, buffering, channel switching time, stability, crash rate, and device-specific behavior. The biggest problems were not always on the devices sitting on an engineer’s desk. They could show up on older or lower-usage hardware that still mattered to the people using the product.

This is where the shared React Native foundation started to pay off. If the team improved a heavy flow once, multiple platforms could benefit from the same work. That did not make React Native inherently faster than native. It made performance work easier to reuse.

The same principle applied to playback, testing, and release. Playback stayed close to the platform when native players were better suited to the job. Testing moved toward behavior-level coverage written once where possible, with platform and white-label differences pushed into helpers. Release moved to one shared code line after each sprint, while platform chapters still handled rollout, monitoring, crash-rate checks, and store-specific steps for their own targets.

The team structure had to move too

A migration like this cannot stay only inside the codebase.

Before React Native, the organization was naturally shaped around platforms. That is what the architecture encouraged. If every platform has its own app, every team needs to own a large slice of the product inside that platform.

The shared React Native stack made another structure possible.

Zattoo moved toward value-stream teams, influenced by Team Topologies. Instead of having platform teams carry the full app experience separately, teams could focus on product areas such as:

  • playback experience
  • content and search
  • signup and account management

This reduces cognitive load. A team can go deeper into one product area and deliver it across platforms, instead of owning every product area for one platform.

Native expertise still matters in this model. Playback needs people who understand the underlying players and platform constraints. SSO has platform-specific details. Operating-system content integrations need native knowledge. Remote input and focus behavior can still differ across devices.

The difference is where that expertise sits.

Instead of isolating all native knowledge in platform silos, it can support product-focused teams where the platform-specific decisions actually happen. In practice, every value stream may still have some device-specific work. React Native changes the amount of duplicated UI and product logic, not the need to understand the platforms.

One lesson from Zattoo’s migration is worth calling out clearly: bring React Native experience into the team early.

React developers can learn React Native. Native developers can learn React Native. But React Native has its own sharp edges, especially on TV. Having someone who has already worked through those edges saves time and helps the team avoid building the wrong abstractions too early.

Where AI fits now

Zattoo started this migration before the current wave of AI-assisted development tools became normal in engineering workflows.

If a team started a similar migration today, AI could help engineers understand unfamiliar legacy code, compare old and new implementations, generate first drafts of tests, explain native project structure to web engineers, or speed up repetitive refactoring.

I would still keep AI in the tooling category. It can reduce friction, especially during onboarding and code exploration, but it does not decide which flows need parity first, where platform behavior should remain native, how releases should work, or how teams should be structured. Those decisions still need product context, engineering judgment, and a good understanding of the platforms.

Practical takeaway

The useful rule from Zattoo’s migration is simple: share implementation until a platform gives you a real reason to split it.

This is less catchy than “write once, run everywhere,” but it is much closer to how TV development works.

React Native did not make TV platforms disappear. It gave Zattoo a better place to manage the parts that were repeated too often: shared product logic, shared UI flows, shared release cadence, shared testing strategy, and shared ownership around product value streams.

For teams thinking about a similar move, the playbook looks something like this:

  • Start with the risky flows: login, backend communication, playback, input, and packaging.
  • Use the existing architecture where it helps, especially shared configuration, utilities, and business logic.
  • Keep platform-specific behavior explicit instead of hiding it behind scattered conditionals.
  • Build testing around behavior, then route the platform differences through helpers.
  • Use telemetry to decide where performance work matters, especially on fragmented platforms like Android TV.
  • Separate code release from platform rollout, and move team ownership toward product areas, not only platforms.
  • Bring React Native experience into the migration early.

The interesting part of Zattoo’s story is not that they replaced native apps with React Native. It's that they used React Native to change how product work moves through the organization.

For a streaming product spread across so many devices, that is where the migration starts to pay off.

Table of contents
Planning a TV app with React Native?

Get expert help to launch your app on Apple TV, Android TV, and other platforms.

Let’s chat

Insights

Learn more about TV

Here's everything we published recently on this topic.