Thanks! We'll be in touch in the next 12 hours
Oops! Something went wrong while submitting the form.

Mastering TV App Development: Building Seamless Experiences with EnactJS and WebOS

Adarsh Singh

Software Development

As the world of smart TVs evolves, delivering immersive and seamless viewing experiences is more crucial than ever. At Velotio Technologies, we take pride in our proven expertise in crafting high-quality TV applications that redefine user engagement. Over the years, we have built multiple TV apps across diverse platforms, and our mastery of cutting-edge JavaScript frameworks, like EnactJS, has consistently set us apart.

Our experience extends to WebOS Open Source Edition (OSE), a versatile and innovative platform for smart device development. WebOS OSE’s seamless integration with EnactJS allows us to deliver native-quality apps optimized for smart TVs that offer advanced features like D-pad navigation, real-time communication with system APIs, and modular UI components.

This blog delves into how we harness the power of WebOS OSE and EnactJS to build scalable, performant TV apps. Learn how Velotio’s expertise in JavaScript frameworks and WebOS technologies drive innovation, creating seamless, future-ready solutions for smart TVs and beyond.

This blog begins by showcasing the unique features and capabilities of WebOS OSE and EnactJS. We then dive into the technical details of my development journey — building a TV app with a web-based UI that communicates with proprietary C++ modules. From designing the app’s architecture to overcoming platform-specific challenges, this guide is a practical resource for developers venturing into WebOS app development.

What Makes WebOS OSE and EnactJS Stand Out?

  • Native-quality apps with web technologies: Develop lightweight, responsive apps using familiar HTML, CSS, and JavaScript.
  • Optimized for TV and beyond: EnactJS offers seamless D-pad navigation and localization for Smart TVs, along with modularity for diverse platforms like automotive and IoT.
  • Real-time integration with system APIs: Use Luna Bus to enable bidirectional communication between the UI and native services.
  • Scalability and customization: Component-based architecture allows easy scaling and adaptation of designs for different use cases.
  • Open source innovation: WebOS OSE provides an open, adaptable platform for developing cutting-edge applications.

What Does This Guide Cover?

The rest of this blog details my development experience, offering insights into the architecture, tools, and strategies for building TV apps:

  • R&D and Designing the Architecture
  • Choosing EnactJS for UI Development
  • Customizing UI Components for Flexibility
  • Navigation Strategy for TV Apps
  • Handling Emulation and Simulation Gaps
  • Setting Up the Development Machine for the Simulator
  • Setting Up the Development Machine for the Emulator
  • Real-Time Updates (Subscription) with Luna Bus Integration
  • Packaging, Deployment, and App Updates

R&D and Designing the Architecture

The app had to connect a web-based interface (HTML, CSS, JS) to proprietary C++ services interacting with system-level processes. This setup is uncommon for WebOS OSE apps, posing two core challenges:

  1. Limited documentation: Resources for WebOS app development were scarce.
  2. WebAssembly infeasibility: Converting the C++ module to WebAssembly would restrict access to system-level processes.

Solution: An Intermediate C++ Service capable of interacting with both the UI and other C++ modules

To bridge these gaps, I implemented an intermediate C++ service to:

  • Communicate between the UI and the proprietary C++ service.
  • Use Luna Bus APIs to send and receive messages.

This approach not only solved the integration challenges but also laid a scalable foundation for future app functionality.

Architecture

The WebApp architecture employs MVVM (Model-View-ViewModel), Component-Based Architecture (CBA), and Atomic Design principles to achieve modularity, reusability, and maintainability.

App Architecture Highlights:

  • WebApp frontend: Web-based UI using EnactJS.
  • External native service: Intermediate C++ service (w/ Client SDK) interacting with the UI via Luna Bus.
Block Diagram of the App Architecture

Choosing EnactJS for UI Development

With the integration architecture in place, I focused on UI development. The D-pad compatibility required for smart TVs narrowed the choice of frameworks to EnactJS, a React-based framework optimized for WebOS apps.

Why EnactJS?

  • Built-in TV compatibility: Supports remote navigation out-of-the-box.
  • React-based syntax: Familiar for front-end developers.

Customizing UI Components for Flexibility

EnactJS’s default components had restrictive customization options and lacked the flexibility for the desired app design.

Solution: A Custom Design Library

I reverse-engineered EnactJS’s building blocks (e.g., Buttons, Toggles, Popovers) and created my own atomic components aligned with the app’s design.

This approach helped in two key ways:

  1. Scalability: The design system allowed me to build complex screens using predefined components quickly.
  2. Flexibility: Complete control over styling and functionality.

Navigation Strategy for TV Apps

In the absence of any recommended navigation tool for WebOS, I employed a straightforward navigation model using conditional-based routing:

  1. High-level flow selection: Determining the current process (e.g., Home, Settings).
  2. Step navigation: Tracking the user’s current step within the selected flow.

This conditional-based routing minimized complexity and avoided adding unnecessary tools like react-router.

Handling Emulation and Simulation Gaps

The WebOS OSE simulator was straightforward to use and compatible with Mac and Linux. However, testing the native C++ services needed a Linux-based emulator.

The Problem: Slow Build Times Cause Slow Development

Building and deploying code on the emulator had long cycles, drastically slowing development.

Solution: Mock Services

To mitigate this, I built a JavaScript-based mock service to replicate the native C++ functionality:

  • On Mac, I used the mock service for rapid UI iterations on the Simulator.
  • On Linux, I swapped the mock service with the real native service for final testing on the Emulator.

This separation of development and testing environments streamlined the process, saving hours during the UI and flow development.

Setting Up the Development Machine for the Simulator

To set up your machine for WebApp development with a simulator, ensure you install the VSCode extensions — webOS Studio, Git, Python3, NVM, and Node.js.

Install WebOS OSE CLI (ares) and configure the TV profile using ares-config. Then, clone the repository, install the dependencies, and run the WebApp in watch mode with npm run watch.

Install the “webOS Studio” extension in VSCode and set up the WebOS TV 24 Simulator via the Package Manager or manually. Finally, deploy and test the app on the simulator using the extension and inspect logs directly from the virtual remote interface.

Note: Ensure the profile is set to TV because the simulator only works only for the TV profile.

CODE: https://gist.github.com/velotiotech/a37b156e2c966074e27d8b9a33260a06.js

Setting Up the Development Machine for the Emulator

To set up your development machine for WebApp and Native Service development with an emulator, ensure you have a Linux machine and WebOS OSE CLI.

Install essential tools like Git, GCC, Make, CMake, Python3, NVM, and VirtualBox.

Build the WebOS Native Development Kit (NDK) using the build-webos repository, which may take 8–10 hours.

Configure the emulator in VirtualBox and add it as a target device using the ares-setup-device. Clone the repositories, build the WebApp and Native Service, package them into an IPK, install it on the emulator using ares-install, and launch the app with ares-launch.

Setting Up the Target Device for Ares Command to be Able to Identify the Emulator

This step is required before you can install the IPK to the emulator.

Note: To find the IP address of the WebOS Emulator, go to Settings -> Network -> Wired Connection.

CODE: https://gist.github.com/velotiotech/d05f5ee9057c8d3efad80c8aadeaef67.js

Real-Time Updates (Subscription) with Luna Bus Integration

One feature required real-time updates from the C++ module to the UI. While the Luna Bus API provided a means to establish a subscription, I encountered challenges with:

  • Lifecycle Management: Re-subscriptions would fail due to improper cleanup.

Solution: Custom Subscription Management

I designed a custom logic layer for stable subscription management, ensuring seamless, real-time updates without interruptions.

Packaging, Deployment, and App Updates

Packaging

Pack a dist of the Enact app, make the native service, and then use the ares-package command to build an IPK containing both the dist and the native service builds.

CODE: https://gist.github.com/velotiotech/331e46b11c4ad2bfeef49cd4d0daa27f.js

Deployment

The external native service will need to be packaged with the UI code to get an IPK, which can then be installed on the WebOS platform manually.

CODE: https://gist.github.com/velotiotech/10e35260799f2fb4c6edca9228f9e21f.js

App Updates

The app updates need to be sent as Firmware-Over-the-Air (FOTA) — based on libostree.

WebOS OSE 2.0.0+ supports Firmware-Over-the-Air (FOTA) using libostree, a “git-like” system for managing Linux filesystem upgrades. It enables atomic version upgrades without reflashing by storing sysroots and tracking filesystem changes efficiently. The setup involves preparing a remote repository on a build machine, configuring webos-local.conf, and building a webos-image. Devices upgrade via commands to fetch and deploy rootfs revisions. Writable filesystem support (hotfix mode) allows temporary or persistent changes. Rollback requires manually reconfiguring boot deployment settings. Supported only on physical devices like Raspberry Pi 4, not emulators, FOTA simplifies platform updates while conserving disk space.

Key Learnings and Recommendations

  1. Mock Early, Test Real: Use mock services for UI development and switch to real services only during final integration.
  2. Build for Reusability: Custom components and a modular architecture saved time during iteration.
  3. Plan for Roadblocks: Niche platforms like WebOS require self-reliance and patience due to limited community support.

Conclusion: Mastering WebOS Development — A Journey of Innovation

Building a WebOS TV app was a rewarding challenge. With WebOS OSE and EnactJS, developers can create native-quality apps using familiar web technologies. WebOS OSE stands out for its high performance, seamless integration, and robust localization support, making it ideal for TV app development and beyond (automotive, IOT, and robotics). Pairing it with EnactJS, a React-based framework, simplifies the process with D-pad compatibility and optimized navigation for TV experiences.

This project showed just how powerful WebOS and EnactJS can be in building apps that bridge web-based UIs and C++ backend services. Leveraging tools like Luna Bus for real-time updates, creating a custom design system, and extending EnactJS’s flexibility allowed for a smooth and scalable development process.

The biggest takeaway is that developing for niche platforms like WebOS requires persistence, creativity, and the right approach. When you face roadblocks and there’s limited help available, try to come up with your own creative solutions, and persist! Keep iterating, learning, and embracing the journey, and you’ll be able to unlock exciting possibilities.

Get the latest engineering blogs delivered straight to your inbox.
No spam. Only expert insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings

Mastering TV App Development: Building Seamless Experiences with EnactJS and WebOS

As the world of smart TVs evolves, delivering immersive and seamless viewing experiences is more crucial than ever. At Velotio Technologies, we take pride in our proven expertise in crafting high-quality TV applications that redefine user engagement. Over the years, we have built multiple TV apps across diverse platforms, and our mastery of cutting-edge JavaScript frameworks, like EnactJS, has consistently set us apart.

Our experience extends to WebOS Open Source Edition (OSE), a versatile and innovative platform for smart device development. WebOS OSE’s seamless integration with EnactJS allows us to deliver native-quality apps optimized for smart TVs that offer advanced features like D-pad navigation, real-time communication with system APIs, and modular UI components.

This blog delves into how we harness the power of WebOS OSE and EnactJS to build scalable, performant TV apps. Learn how Velotio’s expertise in JavaScript frameworks and WebOS technologies drive innovation, creating seamless, future-ready solutions for smart TVs and beyond.

This blog begins by showcasing the unique features and capabilities of WebOS OSE and EnactJS. We then dive into the technical details of my development journey — building a TV app with a web-based UI that communicates with proprietary C++ modules. From designing the app’s architecture to overcoming platform-specific challenges, this guide is a practical resource for developers venturing into WebOS app development.

What Makes WebOS OSE and EnactJS Stand Out?

  • Native-quality apps with web technologies: Develop lightweight, responsive apps using familiar HTML, CSS, and JavaScript.
  • Optimized for TV and beyond: EnactJS offers seamless D-pad navigation and localization for Smart TVs, along with modularity for diverse platforms like automotive and IoT.
  • Real-time integration with system APIs: Use Luna Bus to enable bidirectional communication between the UI and native services.
  • Scalability and customization: Component-based architecture allows easy scaling and adaptation of designs for different use cases.
  • Open source innovation: WebOS OSE provides an open, adaptable platform for developing cutting-edge applications.

What Does This Guide Cover?

The rest of this blog details my development experience, offering insights into the architecture, tools, and strategies for building TV apps:

  • R&D and Designing the Architecture
  • Choosing EnactJS for UI Development
  • Customizing UI Components for Flexibility
  • Navigation Strategy for TV Apps
  • Handling Emulation and Simulation Gaps
  • Setting Up the Development Machine for the Simulator
  • Setting Up the Development Machine for the Emulator
  • Real-Time Updates (Subscription) with Luna Bus Integration
  • Packaging, Deployment, and App Updates

R&D and Designing the Architecture

The app had to connect a web-based interface (HTML, CSS, JS) to proprietary C++ services interacting with system-level processes. This setup is uncommon for WebOS OSE apps, posing two core challenges:

  1. Limited documentation: Resources for WebOS app development were scarce.
  2. WebAssembly infeasibility: Converting the C++ module to WebAssembly would restrict access to system-level processes.

Solution: An Intermediate C++ Service capable of interacting with both the UI and other C++ modules

To bridge these gaps, I implemented an intermediate C++ service to:

  • Communicate between the UI and the proprietary C++ service.
  • Use Luna Bus APIs to send and receive messages.

This approach not only solved the integration challenges but also laid a scalable foundation for future app functionality.

Architecture

The WebApp architecture employs MVVM (Model-View-ViewModel), Component-Based Architecture (CBA), and Atomic Design principles to achieve modularity, reusability, and maintainability.

App Architecture Highlights:

  • WebApp frontend: Web-based UI using EnactJS.
  • External native service: Intermediate C++ service (w/ Client SDK) interacting with the UI via Luna Bus.
Block Diagram of the App Architecture

Choosing EnactJS for UI Development

With the integration architecture in place, I focused on UI development. The D-pad compatibility required for smart TVs narrowed the choice of frameworks to EnactJS, a React-based framework optimized for WebOS apps.

Why EnactJS?

  • Built-in TV compatibility: Supports remote navigation out-of-the-box.
  • React-based syntax: Familiar for front-end developers.

Customizing UI Components for Flexibility

EnactJS’s default components had restrictive customization options and lacked the flexibility for the desired app design.

Solution: A Custom Design Library

I reverse-engineered EnactJS’s building blocks (e.g., Buttons, Toggles, Popovers) and created my own atomic components aligned with the app’s design.

This approach helped in two key ways:

  1. Scalability: The design system allowed me to build complex screens using predefined components quickly.
  2. Flexibility: Complete control over styling and functionality.

Navigation Strategy for TV Apps

In the absence of any recommended navigation tool for WebOS, I employed a straightforward navigation model using conditional-based routing:

  1. High-level flow selection: Determining the current process (e.g., Home, Settings).
  2. Step navigation: Tracking the user’s current step within the selected flow.

This conditional-based routing minimized complexity and avoided adding unnecessary tools like react-router.

Handling Emulation and Simulation Gaps

The WebOS OSE simulator was straightforward to use and compatible with Mac and Linux. However, testing the native C++ services needed a Linux-based emulator.

The Problem: Slow Build Times Cause Slow Development

Building and deploying code on the emulator had long cycles, drastically slowing development.

Solution: Mock Services

To mitigate this, I built a JavaScript-based mock service to replicate the native C++ functionality:

  • On Mac, I used the mock service for rapid UI iterations on the Simulator.
  • On Linux, I swapped the mock service with the real native service for final testing on the Emulator.

This separation of development and testing environments streamlined the process, saving hours during the UI and flow development.

Setting Up the Development Machine for the Simulator

To set up your machine for WebApp development with a simulator, ensure you install the VSCode extensions — webOS Studio, Git, Python3, NVM, and Node.js.

Install WebOS OSE CLI (ares) and configure the TV profile using ares-config. Then, clone the repository, install the dependencies, and run the WebApp in watch mode with npm run watch.

Install the “webOS Studio” extension in VSCode and set up the WebOS TV 24 Simulator via the Package Manager or manually. Finally, deploy and test the app on the simulator using the extension and inspect logs directly from the virtual remote interface.

Note: Ensure the profile is set to TV because the simulator only works only for the TV profile.

CODE: https://gist.github.com/velotiotech/a37b156e2c966074e27d8b9a33260a06.js

Setting Up the Development Machine for the Emulator

To set up your development machine for WebApp and Native Service development with an emulator, ensure you have a Linux machine and WebOS OSE CLI.

Install essential tools like Git, GCC, Make, CMake, Python3, NVM, and VirtualBox.

Build the WebOS Native Development Kit (NDK) using the build-webos repository, which may take 8–10 hours.

Configure the emulator in VirtualBox and add it as a target device using the ares-setup-device. Clone the repositories, build the WebApp and Native Service, package them into an IPK, install it on the emulator using ares-install, and launch the app with ares-launch.

Setting Up the Target Device for Ares Command to be Able to Identify the Emulator

This step is required before you can install the IPK to the emulator.

Note: To find the IP address of the WebOS Emulator, go to Settings -> Network -> Wired Connection.

CODE: https://gist.github.com/velotiotech/d05f5ee9057c8d3efad80c8aadeaef67.js

Real-Time Updates (Subscription) with Luna Bus Integration

One feature required real-time updates from the C++ module to the UI. While the Luna Bus API provided a means to establish a subscription, I encountered challenges with:

  • Lifecycle Management: Re-subscriptions would fail due to improper cleanup.

Solution: Custom Subscription Management

I designed a custom logic layer for stable subscription management, ensuring seamless, real-time updates without interruptions.

Packaging, Deployment, and App Updates

Packaging

Pack a dist of the Enact app, make the native service, and then use the ares-package command to build an IPK containing both the dist and the native service builds.

CODE: https://gist.github.com/velotiotech/331e46b11c4ad2bfeef49cd4d0daa27f.js

Deployment

The external native service will need to be packaged with the UI code to get an IPK, which can then be installed on the WebOS platform manually.

CODE: https://gist.github.com/velotiotech/10e35260799f2fb4c6edca9228f9e21f.js

App Updates

The app updates need to be sent as Firmware-Over-the-Air (FOTA) — based on libostree.

WebOS OSE 2.0.0+ supports Firmware-Over-the-Air (FOTA) using libostree, a “git-like” system for managing Linux filesystem upgrades. It enables atomic version upgrades without reflashing by storing sysroots and tracking filesystem changes efficiently. The setup involves preparing a remote repository on a build machine, configuring webos-local.conf, and building a webos-image. Devices upgrade via commands to fetch and deploy rootfs revisions. Writable filesystem support (hotfix mode) allows temporary or persistent changes. Rollback requires manually reconfiguring boot deployment settings. Supported only on physical devices like Raspberry Pi 4, not emulators, FOTA simplifies platform updates while conserving disk space.

Key Learnings and Recommendations

  1. Mock Early, Test Real: Use mock services for UI development and switch to real services only during final integration.
  2. Build for Reusability: Custom components and a modular architecture saved time during iteration.
  3. Plan for Roadblocks: Niche platforms like WebOS require self-reliance and patience due to limited community support.

Conclusion: Mastering WebOS Development — A Journey of Innovation

Building a WebOS TV app was a rewarding challenge. With WebOS OSE and EnactJS, developers can create native-quality apps using familiar web technologies. WebOS OSE stands out for its high performance, seamless integration, and robust localization support, making it ideal for TV app development and beyond (automotive, IOT, and robotics). Pairing it with EnactJS, a React-based framework, simplifies the process with D-pad compatibility and optimized navigation for TV experiences.

This project showed just how powerful WebOS and EnactJS can be in building apps that bridge web-based UIs and C++ backend services. Leveraging tools like Luna Bus for real-time updates, creating a custom design system, and extending EnactJS’s flexibility allowed for a smooth and scalable development process.

The biggest takeaway is that developing for niche platforms like WebOS requires persistence, creativity, and the right approach. When you face roadblocks and there’s limited help available, try to come up with your own creative solutions, and persist! Keep iterating, learning, and embracing the journey, and you’ll be able to unlock exciting possibilities.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings