A LG tornou o Flutter oficialmente disponível para a webOS TV. Agora dá para construir apps para as smart TVs da LG usando o mesmo framework e a mesma linguagem (Dart) do mobile, com um SDK oficial, plugins de sistema e um fluxo de build e deploy pensado para a plataforma.
Este é um guia prático e completo: do ambiente zerado até o app rodando na TV. Você vai instalar o SDK, preparar o NDK, registrar o dispositivo, criar o projeto, fazer o build do pacote (IPK), instalar na TV e depurar com hot reload. Todos os comandos abaixo são os do fluxo oficial do flutter-webos.

Como o Flutter roda na webOS TV
Por baixo, o app Flutter roda sobre um embedder específico do webOS, com o engine do Flutter portado para a plataforma e um NDK (toolchain) para compilar para a arquitetura da TV. O acesso a recursos do sistema (mídia, ciclo de vida do app, serviços) acontece via plugins que conversam com o Luna Service, o barramento de serviços do webOS. Na sua camada de código, porém, continua sendo Flutter/Dart comum.
Pré-requisitos
- Sistema host: Ubuntu 22.04, 24.04 ou 26.04 para instalação nativa. Em macOS ou Windows, o caminho oficial é o DevContainer em Docker (Windows também aceita WSL2).
- TV alvo: webOS TV a partir do webOS 26 Re:New, com o Modo Desenvolvedor ativado.
- Git 2.23 ou superior.
- Node.js entre 14.15.1 e 16.20.2 e a CLI do webOS (ares) >= 3.2.4.
São dois caminhos: no Linux você instala o toolchain nativamente (passos 1 a 4). No macOS/Windows, use o DevContainer (seção abaixo) — o toolchain já vem pronto e você pula direto para o registro do dispositivo. Os passos de dispositivo, criação, build e deploy são iguais nos dois.
Rodando no macOS (e Windows) com DevContainer
No macOS, o SDK roda dentro de um container Docker já configurado — sem precisar de máquina Linux. Você vai precisar de Docker Desktop, VS Code e a extensão Dev Containers. Comece clonando o repositório do container:
git clone https://github.com/lg-flutter-webos/devcontainer.git
Edite o arquivo .devcontainer/.env e aceite a licença do NDK (obrigatório antes do primeiro build):
WEBOS_NDK_ACCEPT_EULA=1
Abra a pasta no VS Code e escolha Reopen in Container (ou rode “Dev Containers: Reopen in Container” no Command Palette com Ctrl+Shift+P). O VS Code constrói a imagem sozinho a partir do docker-compose. No terminal do container, confirme o ambiente:
flutter-webos doctor -v
Dentro do container já vêm prontos: o flutter-webos (CLI de build/run/package), o webOS NDK (toolchain de cross-compile, que é Linux-only), a CLI ares (empacotamento e instalação de IPK), os artefatos do engine pré-cacheados e os dispositivos personalizados. A versão do NDK dá para trocar em runtime:
webos-ndk install 11.3.0
webos-ndk use 11.3.0
webos-ndk list
webos-ndk current
A partir daí, registrar o dispositivo, criar o projeto, fazer o build, o deploy e o debug (abaixo) é tudo igual — só que rodando dentro do container. O DevTools abre no navegador do seu host, com as portas do Dart VM Service encaminhadas automaticamente (há ainda a opção de GUI via noVNC/VNC nas portas 6080 e 5900).
Atenção no Apple Silicon (M1/M2/M3/M4): o NDK do webOS roda como x86_64 sob emulação, então os builds ficam bem mais lentos que em nativo. Funciona, mas conte com esse custo de tempo nos Macs ARM. Se algum comando reclamar de toolchain faltando, reconstrua o container; se o download do NDK/artefatos falhar, cheque a conectividade do Docker.
Passo 1 — dependências do sistema (Linux)
Comece configurando o Git e instalando as bibliotecas de build:
git --version
git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install curl unzip cmake pkg-config file libgtk-3-0 \
libgtk-3-dev git ninja-build clang git-lfs -y
Passo 2 — instalar o SDK flutter-webos
Clone o SDK e coloque o bin no PATH. Opcionalmente, defina a URL base do engine (de onde os artefatos são baixados):
git clone https://github.com/lg-flutter-webos/flutter-webos.git
cd flutter-webos
export PATH="$PATH:$(pwd)/bin"
# opcional: origem dos artefatos do engine
export WEBOS_ENGINE_BASE_URL="https://github.com/lg-flutter-webos/artifacts/releases/download"
Dica: coloque o export PATH no seu ~/.bashrc (ou ~/.zshrc) para não precisar repetir a cada sessão.
Passo 3 — instalar o webOS NDK
O NDK é o toolchain que compila o app para a arquitetura da TV. Baixe o instalador da release e rode-o, depois exporte o ambiente:
mkdir -p NDK && cd NDK
wget https://github.com/lg-flutter-webos/ndk/releases/download/11.2.0/webos-ndk-flutter-starfish-x86_64-ca9v1-11.2.0.sh
./webos-ndk-flutter-starfish-x86_64-ca9v1-11.2.0.sh -y
export WEBOS_FLUTTER_NDK_ENV="/usr/local/starfish-sdk-x86_64/environment-setup-ca9v1-webosmllib32-linux-gnueabi"
# carregue o ambiente do NDK em cada nova sessão de terminal
. /usr/local/starfish-sdk-x86_64/environment-setup-ca9v1-webosmllib32-linux-gnueabi
Passo 4 — pré-cache e verificação
Baixe os artefatos do engine e rode o doctor para confirmar que está tudo no lugar:
flutter-webos precache
flutter-webos --version
flutter-webos doctor -v
O ideal é ver os checks de Flutter, webOS toolchain e Linux toolchain marcados. Se algum falhar, o próprio doctor aponta o que faltou.
Passo 5 — registrar a TV como dispositivo
Na TV, ative o Modo Desenvolvedor, ligue o Key Server e anote a passphrase. Depois, registre o dispositivo pela CLI:
flutter-webos config --enable-custom-devices
flutter-webos custom-devices add
# informe: um ID único, o IP da TV e a porta SSH (padrão 9922)
# baixe a chave SSH do aparelho
flutter-webos custom-devices get-key -d <seu_device_id>
# confirme que a TV aparece
flutter-webos devices
Passo 6 — criar o app
Crie o projeto com a plataforma webOS habilitada:
flutter-webos create --platforms webos helloworld
cd helloworld
O código é Flutter/Dart normal. Um exemplo mínimo, mas já pensando na tela grande e na navegação por controle remoto (foco visível em botões):
import 'package:flutter/material.dart';
void main() => runApp(const TvApp());
class TvApp extends StatelessWidget {
const TvApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(brightness: Brightness.dark, useMaterial3: true),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Watched $_count times',
style: const TextStyle(fontSize: 48)),
const SizedBox(height: 32),
// FocusableActionDetector / autofocus ajudam na navegação por controle remoto
FilledButton(
autofocus: true,
onPressed: () => setState(() => _count++),
child: const Padding(
padding: EdgeInsets.all(24),
child: Text('Play', style: TextStyle(fontSize: 32)),
),
),
],
),
),
);
}
}
Passo 7 — build do pacote (IPK)
O build gera um IPK, o formato de pacote do webOS. Há três modos:
flutter-webos clean # opcional
flutter-webos build webos --debug # desenvolvimento
flutter-webos build webos --profile # profiling
flutter-webos build webos --release # produção
O IPK sai em um caminho previsível, por modo e arquitetura:
build/webos/{arch}/{mode}/ipk/{id}_{version}_{arch}.ipk
# ex.: build/webos/arm/debug/ipk/com.flutter.app.helloworld_1.0.0_arm.ipk
Passo 8 — deploy e execução na TV
O run compila, instala e sobe o app na TV registrada, no modo escolhido:
flutter-webos run -d <seu_device_id> --debug
flutter-webos run -d <seu_device_id> --profile
flutter-webos run -d <seu_device_id> --release
# para desinstalar da TV
flutter-webos install --uninstall-only -d <seu_device_id>
Depuração com hot reload
Em modo debug, a CLI imprime a URL do Dart VM Service e do Flutter DevTools para depurar pelo navegador. No terminal, os atalhos interativos são os mesmos do Flutter:
flutter-webos run --debug -d <seu_device_id>
# r = hot reload | R = hot restart | d = detach | h = ajuda | q = sair
# reconectar a um app que já está rodando
flutter-webos attach -d <seu_device_id>
Plugins, Luna Service e permissões (ACG)
Para ir além da UI e usar recursos do sistema, o SDK traz um conjunto de plugins prontos. Um panorama por categoria:
- Sistema e Luna Service: webos_service_bridge (ponte para o luna-service2, o coração das APIs do webOS), webos_app_manager (status de apps), webos_display (rotação, limites e orientação da tela), device_info_plus_webos e package_info_plus_webos.
- Mídia: video_player_webos (vídeo inline na árvore de widgets), video_player_drm (conteúdo com DRM), audioplayers_webos e audioplayers_soloud (áudio de baixa latência para jogos), webos_image_texture (textura GPU, com formatos animados).
- Entrada e UI de TV: gamepads_webos (controles/joysticks), flutter_keyboard_visibility_webos, custom_mouse_cursor.
- Armazenamento e dados: shared_preferences_webos, flutter_secure_storage_webos, sqflite_webos (SQLite), path_provider_webos.
- Rede e utilidades: connectivity_plus_webos, url_launcher_webos, webos_lint (regras de lint específicas do webOS).
- Firebase: firebase_core_webos, firebase_auth_webos, firebase_functions_webos, firebase_remote_config_webos e firebase_storage_webos.
A regra prática: quando existe uma versão _webos de um plugin popular (video_player, shared_preferences, connectivity_plus...), use-a no lugar da versão padrão. Chamadas diretas ao Luna Service passam pelo webos_service_bridge.
Algumas APIs exigem permissões via ACG (Access Control Groups): você identifica o grupo necessário no guia de ACG e declara na configuração do app (as permissões são instaladas automaticamente durante o flutter-webos build):
{
"com.example.myapp": ["config"]
}
Dá ainda para ligar o renderizador Impeller, editando webos/meta/flutter-conf.json:
{
"FLUTTER_APP_LOG_PATH": "log",
"engine-switches": {
"enable-impeller": true
}
}
Tocando áudio no app
Áudio é um caso comum e já tem plugin oficial: o audioplayers_webos é a implementação webOS do popular audioplayers (suportado em webOS 26 media ou superior). Ele não é uma implementação endossada, então é preciso declarar os dois no pubspec:
dependencies:
audioplayers: ^6.4.0
audioplayers_webos: ^1.0.0
No código, usa-se a API padrão do audioplayers — nada específico de webOS:
import 'package:audioplayers/audioplayers.dart';
final player = AudioPlayer();
// asset local (declare em flutter: assets: no pubspec)
await player.play(AssetSource('sounds/coins.mp3'));
// stream / URL de áudio
await player.play(UrlSource('https://exemplo.com/musica.mp3'));
await player.setReleaseMode(ReleaseMode.loop); // repetir
await player.pause();
await player.resume();
await player.stop();
await player.dispose();
Para efeitos de baixa latência (jogos, feedback sonoro), existe o audioplayers_soloud, uma implementação webOS alternativa baseada no flutter_soloud.
Limites que valem conhecer (da própria doc do plugin):
- Até 5 AudioPlayers simultâneos por app. Ao passar disso, o player criado há mais tempo é descartado automaticamente (LRU) e recebe um evento de error com código -1 (“num of pipelines”), que dá para detectar no lado Dart.
- HLS (m3u8) com trilha de vídeo não é suportado: o player roda como consumidor só-áudio e não cria janela de vídeo, então um manifesto multi-bitrate com variante de vídeo fica sem áudio. Fontes só-áudio (.mp3, .wav, streams HTTP de MPEG audio) funcionam normalmente.
Para vídeo com áudio e streaming com imagem, o caminho é o video_player_webos (ou video_player_drm para DRM), e não o audioplayers.
Bônus: rodar no Linux desktop
Durante o desenvolvimento, dá para iterar mais rápido rodando no Linux antes de ir para a TV:
flutter-webos create --platforms webos,linux helloworld
flutter-webos build linux
flutter-webos run -d linux
Pontos de atenção
- Host é Linux (Ubuntu). Em macOS/Windows, o caminho oficial é WSL2 ou o DevContainer — não é um fluxo nativo nesses sistemas.
- Alcance: webOS 26 Re:New+. TVs mais antigas ficam de fora por enquanto; pese isso conforme o seu público.
- Versões importam. Node 14.15.1–16.20.2, ares >= 3.2.4, git >= 2.23; a versão do NDK (11.2.0 no exemplo) pode mudar — confira a release atual no repositório.
- Ainda em evolução. A LG sinalizou atualizações no segundo semestre de 2026 (upgrades de versão do Flutter e novos plugins); alguns comandos e artefatos podem mudar — sempre confirme na documentação oficial.
- UI de TV não é UI de celular. Planeje foco visível, navegação por D-pad do controle e áreas de toque grandes; reaproveitar lógica é fácil, mas a camada de UI precisa de adaptação.
Conclusão
Com o SDK oficial, levar Flutter para a webOS TV deixou de ser experimento: existe um caminho reproduzível do ambiente zerado ao IPK instalado na TV, com hot reload, DevTools e acesso a serviços do sistema via plugins. Para quem já vive de Flutter, é mais uma tela de destino usando o que você já sabe.
De olho daqui para frente: acompanhe o repositório no GitHub e as atualizações do segundo semestre de 2026. O melhor próximo passo é prático — rode o helloworld em uma webOS TV 26 Re:New e, a partir dele, meça quanto do seu app atual viaja para a sala de estar. 🚀
Referências
- Anúncio oficial: Flutter for webOS TV is now available for developers (LG webOS TV Developer)
- SDK: github.com/lg-flutter-webos/flutter-webos
- Guia de início: getting-started.md
- DevContainer (macOS/Windows): github.com/lg-flutter-webos/devcontainer
- Plugins: github.com/lg-flutter-webos/plugins
- webOS NDK: github.com/lg-flutter-webos/ndk
- CLI do webOS (ares): webOS TV CLI Developer Guide