An Apple TV-style home screen for LG TVs. It's a webOS port of the launcher from tv-vibehack, which does the same for Android TVs.
Tested on an LG OLED C6 (OLED55C6XLA, webOS 26, firmware 43.21.79).
webOS is more locked down than Android TV, so three things work differently:
| Android TV | LG webOS | |
|---|---|---|
| Install | ADB, no account | LG's Developer Mode app (free LG developer account) |
| App list | read on the TV | read from your computer by sync-apps.py and bundled in; webOS won't let an app list installed apps |
| Home button | the launcher is Home | webOS always opens LG's home; home-watch.py, running on another device, switches straight back (about 0.1 s) |
There's no debloat step: webOS has no ADB-style package disabling. Turn off LG's ads in the TV's own settings instead (see Cleaning up LG's home).
Nothing is rooted. Developer Mode is LG's official way to install your own apps, firmware updates keep working, and deleting the Developer Mode app removes everything.
You need a Mac on the same Wi-Fi as the TV, with Node.js (for LG's ares CLI, fetched with npx)
and Python 3. The steps are macOS only for now: install.sh makes the app icon with sips.
1. Developer Mode on the TV
- Create a free account at webostv.developer.lge.com.
- On the TV, install Developer Mode from the LG Content Store and sign in.
- Turn on Dev Mode Status (the TV restarts), open the app again and turn on Key Server. Note the IP address and Passphrase it shows.
2. Connect your computer (once)
export TV_HOST=192.168.1.50 # the IP from the Developer Mode app
npx -y -p @webos-tools/cli ares-setup-device -a lgtv -i "{'host':'$TV_HOST','port':'9922','username':'prisoner'}"
npx -y -p @webos-tools/cli ares-novacom --device lgtv --getkey # type the passphrase
npx -y -p @webos-tools/cli ares-setup-device -m lgtv -i "{'privatekey':'lgtv_webos','passphrase':'ABC123'}"3. Install
git clone https://github.com/OmkarK97/webos-vibehack.git
cd webos-vibehack
python3 -m venv venv && venv/bin/pip install websockets
TV_HOST=192.168.1.50 ./install.shThe first run shows an "allow this device?" prompt on the TV: accept it. That pairing lets
sync-apps.py read your apps and icons. install.sh then packages the app, installs it and opens
it. Run it again whenever you install or remove apps on the TV.
4. A one-press shortcut
With the launcher open, hold a number key on the remote (say 1) and assign it. From then on, holding 1 opens the launcher from anywhere.
webOS hard-wires Home to LG's home, and blocks Developer Mode apps from seeing which app is in front,
so the TV can't redirect it on its own. home-watch.py does it from another
always-on device on the same network: it watches the TV's foreground app and, the moment LG's home
appears, opens the launcher on top.
- Press Home twice within three seconds to stay on LG's home, for its menus.
- When the TV powers on to LG's home, it goes to the launcher too.
- When the watcher isn't running, Home simply opens LG's home as usual.
On a Mac, install it as a background service that starts at login:
TV_HOST=192.168.1.50 ./home-watch-mac.sh # install or update
./home-watch-mac.sh uninstall # removemacOS will ask for Local Network access for Python: allow it (System Settings → Privacy & Security →
Local Network), or the watcher logs "No route to host". The log is at
~/Library/Logs/tv-vibehack-home-watch.log. A Mac only redirects Home while it's awake and at
home; for every time, run python3 home-watch.py 192.168.1.50 on something that's always on, such
as a Raspberry Pi.
Same as the Android launcher: a dock of four apps with the focused app's name above it and a glow in its colour, the rest of your apps in a grid below, and Inputs (HDMI ports and Live TV), Wi-Fi and Settings at the top. The header slides away when the grid scrolls into it.
Rearrange tiles on the TV: hold OK on a tile until it wiggles, move it with the arrows (into the top row puts it in the dock), then OK to place it or Back to cancel. The order is saved on the TV.
Configure in app/config.js: the starting dock, apps to hide, the Live TV
app and the number of columns. App ids come from venv/bin/python sync-apps.py $TV_HOST --list.
Changing dockApps resets an order arranged on the TV.
For when you do land on it. Names vary a little by webOS version:
- Settings → General → System → Additional Settings → Home Settings: turn off Home Promotion and Content Recommendation.
- Settings → Support → Privacy & Terms → User Agreements: untick Viewing Information and Interest-Based Recommendations.
- Pairing fails with "403 Pairing rejected: blacklisted certificate detected". Newer firmware
rejects the signed manifest that open-source LG clients share.
lgtv.pypairs with an unsigned one, which still works. - No pairing prompt on the TV. Turn on the TV's option for connecting from mobile apps (on the C6: Settings → General → Devices → External Devices; named "LG Connect Apps" or similar).
aressays "All configured authentication methods failed". The device profile is missing its key: run the third command in step 2 again.- Apps stop opening after a while. Developer Mode sessions expire (LG shows the time left in the Developer Mode app; it was 999 hours on our C6). Press Extend Session Time there.
| File | What it does |
|---|---|
app/ |
The launcher: index.html, style.css, app.js, config.js, appinfo.json |
install.sh |
Syncs your apps, packages and installs the launcher, and opens it |
sync-apps.py |
Reads apps, icons and HDMI inputs from the TV into app/apps.js and app/icons/ |
home-watch.py |
Sends the Home button to the launcher |
home-watch-mac.sh |
Runs the watcher as a macOS background service |
lgtv.py |
Pairs with and talks to the TV's remote-control service |
assets/icon.jpg |
The app icon, resized to PNG by install.sh |
The design, layout and app icon come from tv-vibehack
by Gathin. The Outfit font is under the SIL Open Font License
(app/fonts/OFL.txt). MIT licensed, see LICENSE.
