Opaline
August 8, 2026 · View on GitHub
YTLite is now Opaline
The name was too close to YTLite, a popular paid tweak for the official YouTube app, and the two were being mistaken for each other. This project is unrelated to it and has been renamed.
These are the only addresses that stay:
Jailbreak (Cydia, Sileo, Zebra) https://verback2308.github.io/repo/Sideloading (AltStore, SideStore, LiveContainer) https://verback2308.github.io/repo/apps.jsonAnything under
repo.verback2308.pp.uastill answers for now, but it is on its way out and will be switched off — move over while it works. The oldverback2308.github.io/ytliterepo is already gone.Nothing else changes: the update installs over your current one and keeps your account, settings and history.
Screenshots follow your GitHub theme — the app supports both light and dark mode.
Why
When Google dropped support for the official YouTube app on older devices, there was no way to watch videos properly. Browsers capped quality at 360p — and even that barely ran. Opaline was born to restore what was lost: high-quality playback on hardware that still works fine, just ignored by Google — a focused, lightweight client that does one thing well.
Features
- Video playback — up to 1080p 60fps on every device; 2K/4K on hardware with AV1 decode (iPhone 15 Pro and newer, M3+ iPads)
- Shorts — a native full-screen viewer with vertical swiping, likes, comments and sharing; the next short is preloaded so it opens on video rather than a poster. Tapping a short anywhere carries that list into the viewer, and the whole tab can be switched off
- Kids content — plays videos the standard API sources refuse, via a dedicated playback source
- Pinch to zoom — fill the screen in fullscreen with a pinch, or turn on Zoom to Fill to do it automatically
- Background audio — continue listening with the screen off
- Media controls — play/pause and next/previous video from Control Center, the lock screen and headphones
- Picture-in-Picture — watch while using other apps
- SponsorBlock — skip sponsored segments automatically
- Return YouTube Dislike — see dislike counts again
- Audio tracks — switch dubbed audio on multi-language videos, or start videos dubbed in your language automatically; AI auto-dubs are marked "(AI)"
- Subtitles — full subtitle/caption support with VTT parsing
- 12 languages — localized interface, with video titles/search/feeds following your language (see Localization)
- Search & browse — live suggestions, recent-search history, filters (sort, upload date, type, duration), channel pages, playlists
- Smart home feed — endless recommendations with category chips read from your feed's shelves
- Subscriptions — follow channels with a local subscription feed
- Notifications — a bell in the top bar collects app news and new-version announcements, with the full release notes in the message; system notifications are optional and everything still collects in-app if you decline
- Watch history — progress indicators, synced across devices; a video resumes where you left it the moment you reopen it, without waiting for the server to catch up
- Autoplay — automatically play the next related video, with replay, previous and next offered when one ends
- Auto theme — follows system dark mode on iOS 13+, scheduled hours on iOS 12; manual override available
- Made for old hardware — thumbnails and channel details are fetched and decoded a few at a time rather than all at once, which is what keeps scrolling smooth on a dual-core A7
- Your layout — pick the tab the app opens on, force the icon light or dark, and browse settings as a nested menu instead of one long list
Native iPad layout — player and related videos side by side.
More screenshots
Installation
Opaline runs on devices with iOS 12 and above.
Non-jailbroken devices
Option 1 — Add source (recommended)
Add the Opaline source to your sideloading app to receive automatic updates:
Option 2 — Manual install
Download the latest IPA and install via SideStore, AltStore, or LiveContainer.
Option 3 — Build from source
git clone https://github.com/verback2308/Opaline.git
cd Opaline
cp Config/Local.xcconfig.example Config/Local.xcconfig
./make_ipa.sh
Jailbroken devices
Option 1 — Cydia/Sileo repo (recommended)
Add the repo to your package manager to install Opaline and receive automatic updates:
https://verback2308.github.io/repo/
Rootful (iphoneos-arm) and rootless (iphoneos-arm64) packages are provided; Sileo, Zebra and Cydia are supported. Every released version stays available in the repo, so you can also install or roll back to an older one (Sileo/Zebra: package page → version list).
Pick one channel and stay on it — the repo package and the IPA share a bundle identifier, and having both installed leaves an app icon the Home Screen cannot delete. Already have the other one? Remove it first: the IPA from the Home Screen, the repo package from your package manager (or dpkg -r com.verback.ytlite over SSH).
Option 2 — Manual install
Install the .ipa package directly:
- Filza — open the
.ipafile → Install - ReProvision — sign and install the IPA from the app
Known Issues and Limitations
- Playback speeds above 2x may cause issues
- Comments are read-only — you can browse and sort them and open replies, but not post, reply or like
- Offline download is not yet available
- Notification delivery is scheduled by iOS, which grants background time at its own discretion — expect news to arrive within hours of publication, not minutes, and not at all while Background App Refresh or Low Power Mode says otherwise
- Picture in Picture is limited by the system before iOS 15, and no app can work around it: the window survives exactly one video, and switching to another one closes it and leaves audio playing — the full findings are in issue #31
- Before iOS 14.2 the system only starts PiP by itself from fullscreen. Leaving the app while the video plays inline gives background audio instead — the PiP button works in both cases
- Before iOS 15 background audio requires the player to give up its video layer, and the system then refuses to open PiP for that video at all. So once a video has played in the background, automatic PiP no longer starts for it — the PiP button still does, and the next video starts clean
- On a jailbroken device PiP may not start at all — confirmed on an iPad mini 2 running iOS 12.5.8 with Chimera, and likely the same on checkra1n. The jailbreak denies it, not the app; installing ForceInPicture restores it
Localization
The interface follows your system language by default and can be overridden in Settings → Language. The content language (video titles, search, feeds — translated server-side by YouTube, like the official app) follows the app language; the region can be set separately.
Note
All translations except English, Russian and Ukrainian were produced with LLM assistance and then review-passed — mistakes are still possible. If you spot a wrong or awkward translation, please open an issue describing where it appears and what the correct wording should be. To improve a whole language (or add a new one), see TRANSLATING.md.
Available in 12 languages
en English | ru Русский | uk Українська | de Deutsch |
es Español | fr Français | it Italiano | ja 日本語 |
pt Português | tr Türkçe | zh-Hans 简体中文 | zh-Hant 繁體中文 |
Translations for 55 more languages are prepared on the archive/all-languages branch — if you want one of them shipped, open an issue.
Playback Helper Server
The Mobile Web playback source (used for videos the primary source can't open, e.g. kids content) relies on a small companion service. Preparing these streams requires evaluating JavaScript from YouTube's public player page — something iOS 12-era devices can't do on-device. The app delegates that single step to the helper server and receives the computed result back.
What it sees: no account data, no tokens, no cookies, no watch history — only the challenge strings taken from the public player code and the ID of the video being prepared. If you're inspecting traffic and wondering about requests to a non-YouTube host — that's this.
The server's source code will be published later so you can host your own instance and point the app at it (Settings → Debug → Solver Server).
Bug Reports
If you encounter a bug, you can export debug logs directly from the app:
Settings → Debug → Share Debug Log
This generates a log file you can attach to your GitHub issue. The log includes timestamped playback, API, and caching events that help diagnose problems.
For developers
Building
git clone https://github.com/verback2308/Opaline.git
cd Opaline
cp Config/Local.xcconfig.example Config/Local.xcconfig
open Opaline.xcodeproj
Edit Config/Local.xcconfig and set your own PRODUCT_BUNDLE_IDENTIFIER.
APP_MANIFEST_URL in the same file points the update check at a release
manifest — leave the default to follow this repository, or aim it at a file
served from your own machine to test notifications. Release builds get the
URL of whatever repository they are built from, written in by the workflow.
Select the Opaline scheme, choose your device or simulator, and build (⌘B).
Architecture
Opaline/
├── App/ Composition root: AppDelegate, DI wiring, tab bar
├── Core/ Shared kernel (features depend on it, never on each other)
│ ├── API/ YouTube Innertube API client
│ ├── Auth/ OAuth device-code flow
│ ├── Config/ URLs, UserDefaults keys, constants
│ ├── Transport/ HTTP abstraction + decorators
│ ├── Playback/ VideoSource contracts, sources, HLS machinery
│ ├── Services/ Caching, SponsorBlock, RYD, subtitles, watchtime
│ └── Common/ Shared UI components & utilities
└── Features/ One vertical slice per feature
├── Channel/ Channel page with tabs
├── Home/ Home feed
├── Library/ Playlists & saved videos
├── Player/ Video player & watch page
├── Profile/ User profile
├── Search/ Search with suggestions
└── Subscriptions/ Subscription feed
Key Design Decisions
- Zero external dependencies — Networking via a custom
HTTPTransportabstraction overURLSession, images via customThumbnailImageView, playback viaAVPlayer - All UIKit, no SwiftUI — Programmatic layout, no storyboards
- iOS 12+ support — No SF Symbols, no SwiftUI, no Combine
- Manual JSON parsing —
JSONSerialization+ dictionary traversal for YouTube Innertube API responses - Dependency injection —
ServiceContainerprovides services; view controllers receive dependencies via initializers
Playback Pipeline
Playback is built on a single VideoSource abstraction — each way of playing a video implements the same interface and owns both stream resolution and quality selection. PlaybackFacade just asks a factory for the configured source, calls loadPlayback, and hands the prepared AVPlayerItem to the player shell. The sources:
- Auto (default) — Composite: tries Android VR first, transparently falls back to Mobile Web when a video fails to resolve or start.
- Android VR — Streams via YouTube's Innertube API; adaptive formats (360p–1080p AVC, up to 4K AV1 on supported hardware) are converted from DASH SIDX byte ranges into an HLS playlist for native
AVPlayer, with progressive/native-HLS fallbacks. - Mobile Web — Handles videos the Android VR client refuses (e.g. kids content). Stream URLs require solving JavaScript challenges from the player page; that step is delegated to the helper server (see above), everything else stays on-device.
- Progressive — Direct 360p MP4 URL for the restricted case (e.g. server-side A/B experiments).
Quality selection is source-agnostic: the player UI simply renders whatever qualities the active source reports. Background audio is AVAudioSession-based and works across all sources.
Authentication
OAuth device-code flow: the app requests a device code → user enters it at google.com/device → tokens are stored in Keychain. Anonymous browsing is supported.
Project Structure
| Component | Purpose |
|---|---|
InnertubeClient | YouTube API: browse, search, player, comments, subscriptions |
PlaybackFacade | Selects a VideoSource via factory, loads it, and drives player setup |
VideoPlayerView | Custom player UI with controls, gestures, PiP |
WatchViewController | Watch page: player + metadata + comments + related |
AppCache | Dual-layer cache (memory + disk) with TTL |
SponsorBlockController | SponsorBlock API integration |
ThemeManager | App-wide theming (dark/light) |
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -am 'Add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
Please follow the existing code style. SwiftLint is configured and runs as a build phase.
Support
If Opaline keeps your old device alive, you can support development:
Credits
- SponsorBlock — crowdsourced API for skipping sponsored segments
- Return YouTube Dislike — community-maintained dislike count data
- yt-dlp — invaluable reference for understanding YouTube's playback infrastructure
- YouTubeLegacy — inspiration for keeping YouTube alive on older devices
Legal
This project is for educational and personal use. It is not affiliated with, endorsed by, or connected to Google or YouTube. Use at your own risk.
License
GNU General Public License v3.0 — any derivative work must also be released under GPLv3 with its full source code.
