A Clash/meow Android client with a native Jetpack Compose UI, powered by meow-rs and lwip-based tun2socks.
An iOS port is in public beta — see madeye/meow-ios.
Untested builds of the latest main (arm64-v8a) are attached as the meow-arm64-v8a-apk artifact of each APK workflow run. Each one is signed with a throwaway key, so uninstall any other Meow build before installing it.
Compose UI (Kotlin)
| ViewModels over StateFlow; OkHttp to the engine's loopback API
v
Android Native (Kotlin)
| VpnService + AIDL IPC
| JNI (System.loadLibrary)
v
Rust FFI (libmeow_android_ffi.so)
| lwip netstack tun2socks
| Per-socket VpnService.protect() via JNI
v
meow-rs (Cargo dependency)
| Tunnel, Config, Proxy, API
v
Network
- Proxy Protocols: Shadowsocks, Trojan, AnyTLS, Direct
- Shadowsocks plugins: built-in
simple-obfs(HTTP/TLS) andv2ray-plugin(WebSocket, optional TLS) — no external SIP003 binary required
- Shadowsocks plugins: built-in
- Transports: TLS (with ECH), WebSocket, gRPC, HTTP/2, HTTPUpgrade
- Rule Engine: Domain, IP, port, geo-based routing, rule-providers, proxy groups
- tun2socks: Userspace lwIP netstack (patched
lwipcrate) - DNS: Engine-owned fake-IP resolver; every in-TUN DNS query is answered in-process and upstream lookups bypass the tunnel via protected sockets
- Socket Protection: Per-socket
VpnService.protect(fd)via JNI callback - REST API: Embedded external controller (
127.0.0.1:9090) drives the live connections, logs, rules, DNS cache, and traffic views - Compose UI: Shadowrocket-style tab view, styled to match the iOS app
- Home: VPN toggle, connection status, route mode (Rule / Global / Direct,
remembered across reconnects) and the live Rules view; the top-right
button opens Subscriptions: switch profiles, add/edit/remove, share/scan
them as QR codes, YAML editor, import/export config, and update a
profile's rule sets (
rule-providers:) on demand while connected. Subscription configs are read-only, as on Surge (every update replaces them): create a copy to edit one - Proxy Groups: proxy group & node selection, per-group latency tests
- Utility: live Connections and DNS-cache views powered by the REST API, Traffic (real-time speed chart, session upload/download stats, daily history) and Logs, grouped as on the iOS app
- Settings: Version, network config, per-app VPN proxy/bypass, connectivity diagnostics, about
- Home: VPN toggle, connection status, route mode (Rule / Global / Direct,
remembered across reconnects) and the live Rules view; the top-right
button opens Subscriptions: switch profiles, add/edit/remove, share/scan
them as QR codes, YAML editor, import/export config, and update a
profile's rule sets (
- i18n: English, Chinese (zh_CN), Russian, Persian, Arabic, Vietnamese, Turkish, Burmese (Persian and Arabic right-to-left); on Android 13+ the language can be set per app in system settings
- E2E Tests: Automated with ssserver + Android emulator (SS and HTTP-proxy harnesses)
- Android SDK (API 36) with NDK 27.0.12077973 (AGP 8.13's default
ndkVersion) - Rust toolchain with Android targets:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android - JDK 17–25
# Build debug APK (arm64 only, release Rust)
export JAVA_HOME=/path/to/jdk
./gradlew :mobile:assembleDebug -PTARGET_ABI=arm64 -PCARGO_PROFILE=releaseThe APK is at mobile/build/outputs/apk/debug/mobile-debug.apk.
# Requires: ssserver, Android emulator, adb
./test-e2e.shcore/ Android library module
src/main/java/ Kotlin: VPN service, AIDL, Room DB
src/main/rust/
meow-android-ffi/ Rust FFI crate (JNI + tun2socks)
src/main/java/.../api/ Engine controller client (REST + websocket)
src/main/java/.../repo/ Profiles, per-app proxy, traffic history
mobile/ Android app module (Compose UI host)
src/main/java/.../ui/theme/ Brand tokens shared with the iOS app
src/main/java/.../ui/screens/ Home, Subscribe, Utility, Settings,
Traffic, Connections, Logs, DNS, Rules,
Per-app proxy, YAML editor
src/main/res/values{,-zh-rCN,-ru,-fa,-ar,-vi,-tr,-my}
Localization (en, zh_CN, ru, fa)
test-e2e.sh End-to-end test script (Shadowsocks)
test-e2e-http.sh End-to-end test script (HTTP proxy)
MIT - Max Lv max.c.lv@gmail.com

