Love Iwara (i-iwara or 2i). An unofficial iwara flutter app - Supporting multiple platforms and devices including mobile phones, tablets and computers. Compatible with Android, Meta Horizon OS, Windows and other systems. 第三方的Iwara应用 - 支持多个平台和设备,包括手机、平板和计算机。兼容 安卓、Meta Horizon OS、IOS、Windows、MacOS等系统。
Dart
1,448
1,243 commits
updated Sep 22, 2026
A fast, beautiful, cross-platform third-party Iwara client built with Flutter.
One codebase → Android · Meta Quest · Windows · macOS · Linux · iOS
English · 日本語 · 简体中文 · 繁體中文 · 한국어 · ภาษาไทย · Bahasa Indonesia · Tiếng Việt · Español · Русский · Français · Deutsch
Love Iwara (also known as i_iwara or 2i) is a third-party client for Iwara built with Flutter. It aims to deliver a smooth, native-feeling experience across phones, tablets, and desktops — all from a single codebase covering Android, Meta Quest, Windows, macOS, Linux, and iOS.
[!NOTE] This started as a learning project — my first attempt at a cross-platform Flutter app. Some code may not be perfectly polished, but it's actively maintained and packed with features. If you're learning Flutter too, I hope we can grow together. PRs and feedback are always welcome!
[!IMPORTANT] Usage restrictions — This project is for learning and personal reference only and is not recommended for production use. Promotion of this project on any public platform is strictly prohibited. Violations may result in maintenance being halted and the repository being removed.
[!WARNING] Disclaimer — The developer(s) have no affiliation with Iwara or its content providers. This application hosts zero content of its own.
| Android | Meta Quest | Windows | macOS | Linux | iOS |
|---|---|---|---|---|---|
| ✅ | ✅ separate APK¹ | ✅ | ✅ | ⚠️ untested² | ✅ |
¹ The Quest build is its own arm64 APK for Horizon OS (Android 14+) carrying the Meta Spatial SDK — see Meta Quest / VR. The regular Android APK is unaffected and still supports Android 7.0+. ² Linux builds are produced but currently untested due to a lack of test devices.
Shipped as a separate quest APK built on the Meta Spatial SDK. The regular Android build links none of it and keeps its minSdk where it is.
The app lives in a spatial environment. Launching from the Quest home drops you straight into a resident immersive space. The entire app — browsing, search, comments, the soft keyboard — floats in front of you as a 2D panel; nothing about it is cut down. The panel is gently curved (a 30° arc — about a "3000R" monitor at its default 1.6 m width). It's the arc that's fixed, not the radius, so the curve looks the same however wide or narrow you drag the window.
Three windows, one set of gestures. The app panel, the screen and the control panel each carry their own frame: the grip trigger drags a window by its body, the edges drag and the corners resize it around its centre, and windows keep facing you. Sizes and positions are remembered. Nothing appears until head tracking has settled — no window flashing up in the wrong place and then jumping.
The player becomes a screen in the space. Open a video and it hands off automatically (optional).
Spatial gallery. A gallery opens as one large stage plus a film strip, so a set of dozens of images — and the videos mixed in among them — stays a single object rather than dozens of layers. Slideshow at 3 / 5 / 10 / 20 s, standard or original quality, and a sideways drag on the stage to flip. Portrait images are fitted into a 16:9 box so a 9:16 illustration doesn't tower over you.
Hands or controllers.
A first run starts with a lesson. The headset's first-time guide isn't the touchscreen one ("pinch to zoom, hold for speed") carried over — there's no touchable picture in the space. Instead there are two courses, spatial video and spatial gallery: a controller illustration animates frame by frame along with its buttons and stick, the screen, panels and rays sit at their real geometry, and every move is shown for controllers and for bare hands. With the system's "reduce motion" on it draws a single informative still frame instead. Replayable any time from settings.
iwara.tv and iwara.ai at runtimenews.iwara.tv)12 UI languages — English · 简体中文 · 繁體中文 · 日本語 · 한국어 · ภาษาไทย · Bahasa Indonesia · Tiếng Việt · Español · Русский · Français · Deutsch — including the spatial panels on Quest, which follow the app's language rather than the system's. Iwara/Oreno3d tag names are translated for a smaller set of these languages — see below.
Found something else? There are more hidden gems to discover — and more on the way. Got an idea? Open an Issue or drop by the Telegram group.
Quest support has landed — see Meta Quest / VR above. It ships as its own APK, produced by its own CI job, and the regular Android build is untouched.
Still open on the headset side:
Elsewhere: downloads are still marked beta, and Linux is built but untested for want of a test machine.
Got a request? Open an Issue or drop by the Telegram group.
| Area | Library |
|---|---|
| Framework | Flutter + Dart |
| State management | GetX (get) |
| Routing | go_router |
| Networking | Dio (+ CookieJar / Cloudflare interceptors) |
| Video | media_kit (libmpv) |
| Persistence | sqlite3 · get_storage · flutter_secure_storage |
| i18n | slang |
| Desktop shell | window_manager (custom title bar, drag & drop) |
| The screen and its control panel | A gallery: one stage plus a film strip |
|---|---|
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
# 1. Clone
git clone https://github.com/FoxSensei001/LoveIwara.git
cd LoveIwara
# 2. Verify your toolchain
flutter doctor
# 3. Install dependencies
flutter pub get
# 4. Run (auto-selects a connected device)
flutter run --flavor standard # Android requires a flavor — see the note below
# …or target a platform (desktop/iOS need no flavor):
flutter run -d windows # macos / linux / ios
[!IMPORTANT] Android ships two product flavors.
standardis the regular phone/tablet build (minSdk 24, all ABIs);questis the Meta Quest / Horizon OS build (minSdk 34, arm64 only, bundles the ~50 MB Meta Spatial SDK). Once flavors exist, AGP no longer has a "no flavor" variant, so every Androidflutter run/flutter buildmust pass--flavor— a bare command fails outright.
[!TIP] After editing any
lib/i18n/*.i18n.yaml, regenerate the localization strings withdart run slang. Seepubspec.yamlfor the full dependency list — a few packages need extra setup steps.
Windows
flutter doctor -v
macOS
sudo gem install cocoapods
Linux
# Ubuntu/Debian
sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
# Fedora
sudo dnf install clang cmake ninja-build gtk3-devel
Android — Android Studio + Android SDK + emulator/device iOS — Xcode + simulator/device + Apple Developer account (for publishing)
flutter build apk --release --flavor standard # Android APK (phones / tablets)
flutter build appbundle --release --flavor standard # Android AAB
flutter build apk --release --flavor quest --target-platform android-arm64 # Meta Quest APK
flutter build ios --release # iOS
flutter build windows --release # Windows
flutter build macos --release # macOS
flutter build linux --release # Linux
dart run slang # regenerate i18n strings
flutter analyze # lint
flutter test # run tests
flutter clean # clear build cache
flutter devices # list connected devices
# Dependency conflicts
flutter pub cache repair && flutter clean && flutter pub get
# Emulator
flutter emulators && flutter emulators --launch <emulator_id>
To build a signed release APK:
1. Generate a keystore (run inside android/app):
keytool -genkeypair -v -keystore keystore.jks -alias <your_key_alias> -keyalg RSA -keysize 2048 -validity 10000
Make sure keystore.jks ends up in android/app.
2. Configure signing in android/app/build.gradle:
signingConfigs {
release {
storeFile file("keystore.jks")
storePassword System.getenv("KEYSTORE_PASSWORD") ?: project.findProperty("MY_KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS") ?: project.findProperty("MY_KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD") ?: project.findProperty("MY_KEY_PASSWORD")
}
}
And add the placeholders to android/gradle.properties:
MY_KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD}
MY_KEY_ALIAS=${KEY_ALIAS}
MY_KEY_PASSWORD=${KEY_PASSWORD}
3. GitHub Actions — add repository Secrets: KEYSTORE_BASE64 (base64 of keystore.jks), KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD. Then in .github/workflows/build.yml:
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
steps:
- name: Setup Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/keystore.jks
shell: bash
4. Build — flutter build apk --release --flavor standard → output at build/app/outputs/flutter-apk/app-standard-release.apk. For the Quest build, flutter build apk --release --flavor quest --target-platform android-arm64 → app-arm64-v8a-quest-release.apk.
The UI now ships in 12 languages; translations are mostly machine-generated except for the original four (English / 简体中文 / 繁體中文 / 日本語), which are human-reviewed. If you'd like to help improve a translation, start from the Simplified Chinese template: lib/i18n/zh-CN.i18n.yaml, then run dart run slang. See docs/i18n/README.md for the full per-language status and maintenance commands.
Iwara's raw tags are English-ish keys (e.g. mother, blue_archive). The app ships a community-maintained dictionary that maps every tag to Simplified Chinese / Traditional Chinese / Japanese / English, so tags render in your current language across detail pages, search, and the tag list page.
How it works:
tool/data/iwara_tags/. The app consumes the merged, minified iwara_tags.min.json.assets/data/iwara_tags.min.json) and hot-updated from the jsDelivr CDN — so wording can improve without shipping a new app build.These are best-effort translations of 2600+ ACG / Vtuber / NSFW terms and may contain mistakes.
Spotted a wrong or awkward translation? Please report it on the dedicated issue: https://github.com/FoxSensei001/LoveIwara/issues/98 (the in-app tag dialog links here too).
Contributing a fix (for maintainers/contributors):
iwara_tags_localized.json (per-tag zh-CN / zh-TW / ja / en).dart run tool/data/iwara_tags/build_localized_min.dart.iwara_tags.min.json (see tool/data/iwara_tags/README.md).The third-party Oreno3d metadata (origins / characters / tags) is localized the same way — dictionary in tool/data/oreno3d_tags/, bundled asset + jsDelivr CDN, shown in your current language on the video detail page and search cards.
[!NOTE] Both tag dictionaries above are maintained for zh-CN / zh-TW / ja / en only — they are not extended to the other 8 UI languages (ko / th / id / vi / es / ru / fr / de). These are 2600+ ACG / Vtuber / doujin-slang terms that lean on subculture-specific phrasing rather than literal translation; scaling AI translation to 12 languages without anyone able to review the result risks silently-wrong tags nobody catches. In UI languages outside those four, tags aren't translated into that language — they fall back to the dictionary's English name instead (e.g.
mother→Mother). Only a tag missing from the dictionary entirely falls back to its raw key, and that happens regardless of UI language. Details and rationale:docs/i18n/README.md.
This project drew inspiration and learned many best practices from these excellent repositories:
Thanks to everyone who has contributed! 🎉
Made with contrib.rocks
Pull requests are welcome! For major changes, please open an issue first to discuss what you'd like to change. Before reporting a new issue, check the existing issues. Questions? Join our Telegram group.
Join us on Telegram: Click here to join the group.
Dart
84.5%
GLSL
10.4%
Kotlin
4.0%
Love Iwara (i-iwara or 2i). An unofficial iwara flutter app - Supporting multiple platforms and devices including mobile phones, tablets and computers. Compatible with Android, Meta Horizon OS, Windows and other systems. 第三方的Iwara应用 - 支持多个平台和设备,包括手机、平板和计算机。兼容 安卓、Meta Horizon OS、IOS、Windows、MacOS等系统。
Dart
1,448
1,243 commits
updated Sep 22, 2026
A fast, beautiful, cross-platform third-party Iwara client built with Flutter.
One codebase → Android · Meta Quest · Windows · macOS · Linux · iOS
English · 日本語 · 简体中文 · 繁體中文 · 한국어 · ภาษาไทย · Bahasa Indonesia · Tiếng Việt · Español · Русский · Français · Deutsch
Love Iwara (also known as i_iwara or 2i) is a third-party client for Iwara built with Flutter. It aims to deliver a smooth, native-feeling experience across phones, tablets, and desktops — all from a single codebase covering Android, Meta Quest, Windows, macOS, Linux, and iOS.
[!NOTE] This started as a learning project — my first attempt at a cross-platform Flutter app. Some code may not be perfectly polished, but it's actively maintained and packed with features. If you're learning Flutter too, I hope we can grow together. PRs and feedback are always welcome!
[!IMPORTANT] Usage restrictions — This project is for learning and personal reference only and is not recommended for production use. Promotion of this project on any public platform is strictly prohibited. Violations may result in maintenance being halted and the repository being removed.
[!WARNING] Disclaimer — The developer(s) have no affiliation with Iwara or its content providers. This application hosts zero content of its own.
| Android | Meta Quest | Windows | macOS | Linux | iOS |
|---|---|---|---|---|---|
| ✅ | ✅ separate APK¹ | ✅ | ✅ | ⚠️ untested² | ✅ |
¹ The Quest build is its own arm64 APK for Horizon OS (Android 14+) carrying the Meta Spatial SDK — see Meta Quest / VR. The regular Android APK is unaffected and still supports Android 7.0+. ² Linux builds are produced but currently untested due to a lack of test devices.
Shipped as a separate quest APK built on the Meta Spatial SDK. The regular Android build links none of it and keeps its minSdk where it is.
The app lives in a spatial environment. Launching from the Quest home drops you straight into a resident immersive space. The entire app — browsing, search, comments, the soft keyboard — floats in front of you as a 2D panel; nothing about it is cut down. The panel is gently curved (a 30° arc — about a "3000R" monitor at its default 1.6 m width). It's the arc that's fixed, not the radius, so the curve looks the same however wide or narrow you drag the window.
Three windows, one set of gestures. The app panel, the screen and the control panel each carry their own frame: the grip trigger drags a window by its body, the edges drag and the corners resize it around its centre, and windows keep facing you. Sizes and positions are remembered. Nothing appears until head tracking has settled — no window flashing up in the wrong place and then jumping.
The player becomes a screen in the space. Open a video and it hands off automatically (optional).
Spatial gallery. A gallery opens as one large stage plus a film strip, so a set of dozens of images — and the videos mixed in among them — stays a single object rather than dozens of layers. Slideshow at 3 / 5 / 10 / 20 s, standard or original quality, and a sideways drag on the stage to flip. Portrait images are fitted into a 16:9 box so a 9:16 illustration doesn't tower over you.
Hands or controllers.
A first run starts with a lesson. The headset's first-time guide isn't the touchscreen one ("pinch to zoom, hold for speed") carried over — there's no touchable picture in the space. Instead there are two courses, spatial video and spatial gallery: a controller illustration animates frame by frame along with its buttons and stick, the screen, panels and rays sit at their real geometry, and every move is shown for controllers and for bare hands. With the system's "reduce motion" on it draws a single informative still frame instead. Replayable any time from settings.
iwara.tv and iwara.ai at runtimenews.iwara.tv)12 UI languages — English · 简体中文 · 繁體中文 · 日本語 · 한국어 · ภาษาไทย · Bahasa Indonesia · Tiếng Việt · Español · Русский · Français · Deutsch — including the spatial panels on Quest, which follow the app's language rather than the system's. Iwara/Oreno3d tag names are translated for a smaller set of these languages — see below.
Found something else? There are more hidden gems to discover — and more on the way. Got an idea? Open an Issue or drop by the Telegram group.
Quest support has landed — see Meta Quest / VR above. It ships as its own APK, produced by its own CI job, and the regular Android build is untouched.
Still open on the headset side:
Elsewhere: downloads are still marked beta, and Linux is built but untested for want of a test machine.
Got a request? Open an Issue or drop by the Telegram group.
| Area | Library |
|---|---|
| Framework | Flutter + Dart |
| State management | GetX (get) |
| Routing | go_router |
| Networking | Dio (+ CookieJar / Cloudflare interceptors) |
| Video | media_kit (libmpv) |
| Persistence | sqlite3 · get_storage · flutter_secure_storage |
| i18n | slang |
| Desktop shell | window_manager (custom title bar, drag & drop) |
| The screen and its control panel | A gallery: one stage plus a film strip |
|---|---|
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
# 1. Clone
git clone https://github.com/FoxSensei001/LoveIwara.git
cd LoveIwara
# 2. Verify your toolchain
flutter doctor
# 3. Install dependencies
flutter pub get
# 4. Run (auto-selects a connected device)
flutter run --flavor standard # Android requires a flavor — see the note below
# …or target a platform (desktop/iOS need no flavor):
flutter run -d windows # macos / linux / ios
[!IMPORTANT] Android ships two product flavors.
standardis the regular phone/tablet build (minSdk 24, all ABIs);questis the Meta Quest / Horizon OS build (minSdk 34, arm64 only, bundles the ~50 MB Meta Spatial SDK). Once flavors exist, AGP no longer has a "no flavor" variant, so every Androidflutter run/flutter buildmust pass--flavor— a bare command fails outright.
[!TIP] After editing any
lib/i18n/*.i18n.yaml, regenerate the localization strings withdart run slang. Seepubspec.yamlfor the full dependency list — a few packages need extra setup steps.
Windows
flutter doctor -v
macOS
sudo gem install cocoapods
Linux
# Ubuntu/Debian
sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
# Fedora
sudo dnf install clang cmake ninja-build gtk3-devel
Android — Android Studio + Android SDK + emulator/device iOS — Xcode + simulator/device + Apple Developer account (for publishing)
flutter build apk --release --flavor standard # Android APK (phones / tablets)
flutter build appbundle --release --flavor standard # Android AAB
flutter build apk --release --flavor quest --target-platform android-arm64 # Meta Quest APK
flutter build ios --release # iOS
flutter build windows --release # Windows
flutter build macos --release # macOS
flutter build linux --release # Linux
dart run slang # regenerate i18n strings
flutter analyze # lint
flutter test # run tests
flutter clean # clear build cache
flutter devices # list connected devices
# Dependency conflicts
flutter pub cache repair && flutter clean && flutter pub get
# Emulator
flutter emulators && flutter emulators --launch <emulator_id>
To build a signed release APK:
1. Generate a keystore (run inside android/app):
keytool -genkeypair -v -keystore keystore.jks -alias <your_key_alias> -keyalg RSA -keysize 2048 -validity 10000
Make sure keystore.jks ends up in android/app.
2. Configure signing in android/app/build.gradle:
signingConfigs {
release {
storeFile file("keystore.jks")
storePassword System.getenv("KEYSTORE_PASSWORD") ?: project.findProperty("MY_KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS") ?: project.findProperty("MY_KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD") ?: project.findProperty("MY_KEY_PASSWORD")
}
}
And add the placeholders to android/gradle.properties:
MY_KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD}
MY_KEY_ALIAS=${KEY_ALIAS}
MY_KEY_PASSWORD=${KEY_PASSWORD}
3. GitHub Actions — add repository Secrets: KEYSTORE_BASE64 (base64 of keystore.jks), KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD. Then in .github/workflows/build.yml:
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
steps:
- name: Setup Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/keystore.jks
shell: bash
4. Build — flutter build apk --release --flavor standard → output at build/app/outputs/flutter-apk/app-standard-release.apk. For the Quest build, flutter build apk --release --flavor quest --target-platform android-arm64 → app-arm64-v8a-quest-release.apk.
The UI now ships in 12 languages; translations are mostly machine-generated except for the original four (English / 简体中文 / 繁體中文 / 日本語), which are human-reviewed. If you'd like to help improve a translation, start from the Simplified Chinese template: lib/i18n/zh-CN.i18n.yaml, then run dart run slang. See docs/i18n/README.md for the full per-language status and maintenance commands.
Iwara's raw tags are English-ish keys (e.g. mother, blue_archive). The app ships a community-maintained dictionary that maps every tag to Simplified Chinese / Traditional Chinese / Japanese / English, so tags render in your current language across detail pages, search, and the tag list page.
How it works:
tool/data/iwara_tags/. The app consumes the merged, minified iwara_tags.min.json.assets/data/iwara_tags.min.json) and hot-updated from the jsDelivr CDN — so wording can improve without shipping a new app build.These are best-effort translations of 2600+ ACG / Vtuber / NSFW terms and may contain mistakes.
Spotted a wrong or awkward translation? Please report it on the dedicated issue: https://github.com/FoxSensei001/LoveIwara/issues/98 (the in-app tag dialog links here too).
Contributing a fix (for maintainers/contributors):
iwara_tags_localized.json (per-tag zh-CN / zh-TW / ja / en).dart run tool/data/iwara_tags/build_localized_min.dart.iwara_tags.min.json (see tool/data/iwara_tags/README.md).The third-party Oreno3d metadata (origins / characters / tags) is localized the same way — dictionary in tool/data/oreno3d_tags/, bundled asset + jsDelivr CDN, shown in your current language on the video detail page and search cards.
[!NOTE] Both tag dictionaries above are maintained for zh-CN / zh-TW / ja / en only — they are not extended to the other 8 UI languages (ko / th / id / vi / es / ru / fr / de). These are 2600+ ACG / Vtuber / doujin-slang terms that lean on subculture-specific phrasing rather than literal translation; scaling AI translation to 12 languages without anyone able to review the result risks silently-wrong tags nobody catches. In UI languages outside those four, tags aren't translated into that language — they fall back to the dictionary's English name instead (e.g.
mother→Mother). Only a tag missing from the dictionary entirely falls back to its raw key, and that happens regardless of UI language. Details and rationale:docs/i18n/README.md.
This project drew inspiration and learned many best practices from these excellent repositories:
Thanks to everyone who has contributed! 🎉
Made with contrib.rocks
Pull requests are welcome! For major changes, please open an issue first to discuss what you'd like to change. Before reporting a new issue, check the existing issues. Questions? Join our Telegram group.
Join us on Telegram: Click here to join the group.
Dart
84.5%
GLSL
10.4%
Kotlin
4.0%