SimpleXray is primarily an Android frontend and launcher for Xray-core. It accepts complete Xray-core configuration files in JSON or YAML format and executes the resulting configuration on Android.
The application does not parse or generate configurations from share links or subscription URIs such as vless://, vmess://, or trojan://. Users are expected to have a basic understanding of Xray-core configuration files.
Imported configurations may be processed before execution to accommodate Android-specific requirements. This includes removing or modifying configuration elements that are specific to desktop or root environments.
This repository is a personal fork based on the upstream SimpleXray project.
Note
This repository is a personal fork maintained strictly for personal use and experimentation. Public Issues and Pull Requests are not accepted, and no support or maintenance is provided. If you wish to use the app or track newer kernel updates, feel free to fork this project and build it via CI.
Click to expand / collapse: Differences from Upstream
| Area | Upstream (4c78901) | Personal Fork |
|---|---|---|
| Configuration Import | JSON configurations, vless:// links, and simplexray://config/ links |
Full JSON and YAML configurations imported through the Storage Access Framework (SAF) or clipboard; share links are not supported |
| Rule Files | Embedded geoip.dat and geosite.dat files, with local replacement and URL updates for these two files |
Retains the standard rule-file management and adds arbitrary custom .dat files, ext: file references, per-file update URLs, validation, and background updates |
| Configuration Sanitization | JSON formatting with removal of log.access and log.error |
SnakeYAML-based parsing with a one-way Android compatibility pipeline that modifies inbounds, routing rules, DNS bootstrap hosts, logging, and selected outbound settings |
| Build System | Legacy ndkBuild (Android.mk) and standard Gradle configuration |
CMake (CMakeLists.txt); the native tunnel target includes Android 16 KB page-alignment linker options. Gradle Wrapper 9.7.0, Android Gradle Plugin 9.3.1, Version Catalogs, and Plugins DSL |
| UI & Layout | Standard Material 3 UI | Xiaomi HyperOS / MIUI-inspired UI implemented with compose-miuix-ui, with adaptive layouts for phones and large screens, NavigationRail support, and Android 12+ dynamic colors |
| Persistence & Communication | ContentProvider-backed SharedPreferences and Gson |
Direct lightweight SharedPreferences with kotlinx.serialization; UI and background service communicate reactively via in-memory StateFlow and SharedFlow |
| Core Components | Xray-core v26.3.27 and hev-socks5-tunnel v2.14.3 |
Xray-core v26.9.30, sing-tun (Go stack), and hev-socks5-tunnel v2.18.0, including updated hev-socks5-core, hev-task-system, and lwip components |
| ABI Packaging | arm64-v8a and x86_64 split APKs, plus a universal APK |
arm64-v8a APK only |
| TUN Backend Setting | No Xray TUN backend setting | Xray TUN, SingTUN, and Hev Socks5 Tunnel selector, defaulting to Hev Socks5 Tunnel |
The user interface has been refactored around compose-miuix-ui, using a design language inspired by Xiaomi HyperOS / MIUI.
- Miuix components: Uses Miuix components and shapes, including
TopAppBar,Card,InputField,Checkbox,OverlayIconDropdownMenu,OverlayDialog, andOverlayBottomSheet. - Theme support: Provides Light, Dark, and Automatic theme modes, together with Android 12+ Monet dynamic colors integrated with the Miuix color scheme.
- Adaptive navigation: Uses a vertical Miuix
NavigationRailon wide screens whenscreenWidthDp >= 600dp. - Master-detail layout: Uses a dual-pane layout for
ConfigScreenon larger landscape displays whenscreenWidthDp >= 840dp, allowing profile selection and configuration editing to be displayed side by side. - Editor layout: Provides a fullscreen editor mode. Dashboard, Settings, and App-Based Proxy content use a maximum width of
840dpon wide screens. - Edge-to-edge navigation: Uses a floating navigation bar that allows page content to scroll beneath the translucent navigation surface.
- Per-app proxy filtering: Adds an option in the App-Based Proxy screen to show or hide applications that do not declare
android.permission.INTERNET. - Direct controls: Provides direct controls for log search, log export, log clearing, and dashboard latency refresh. Configuration import remains available from the configuration screen.
SimpleXray accepts complete Xray-core configuration files rather than individual proxy nodes or share links.
Supported input formats include:
- JSON configuration files;
- YAML configuration files;
.json,.yaml, and.ymlfiles imported through the Android Storage Access Framework (SAF);- Configuration text pasted from the clipboard.
Share links and subscription URIs, such as vless://, vmess://, and trojan://, are not supported.
YAML configurations are parsed into structured data, processed by the configuration sanitization pipeline, and serialized before being passed to Xray-core.
The application also provides an in-app configuration editor with text editing, search, and bracket matching.
SimpleXray retains the embedded geoip.dat and geosite.dat rule files and provides additional local and remote management capabilities.
- Local replacement: Import local
geoip.datandgeosite.datfiles from device storage. - Custom rule files: Import and manage arbitrary non-standard
.datfiles. - Custom tags: Support custom rule references such as
ext:custom.dat:subcategory. - Per-file update URLs: Configure individual update URLs for non-standard
.datfiles. - Background updates: Download configured custom rule files in the background.
SimpleXray uses separate channels for configuration, VPN traffic, process logs, and statistics queries.
- Single-Process Application Architecture: The Android app layer (UI and background
TProxyService) runs in a unified process, eliminating multi-process IPC overhead. Service state and log streams are delivered via in-memoryStateFlow/SharedFlow, with lightweight directSharedPreferencespersistence. - Core Sub-Process Execution: Xray-core runs as an independent OS-level child process, enabling decoupled management and drop-in kernel upgrades. Generated JSON is written directly to Xray-core through stdin without intermediate config files on disk.
- Native TUN mode: The JNI launcher passes the Android
VpnServicefile descriptor to the Xray child process, which attaches it to the TUN inbound. - Process logs: Xray stdout and stderr are collected through pipes and broadcast directly to the UI via memory flows.
- Statistics: Core status and traffic statistics are queried through plaintext gRPC on a dynamically allocated
127.0.0.1ephemeral TCP port. - SingTUN mode: Powered by
sing-tun's new self-developed pure Go user-space network stack (Zero-Alloc slab pools, hierarchical timing wheel, and userspace zero-copy pipelines), reads the Android VPN file descriptor and streams traffic to Xray's local SOCKS5 inbound. - Hev tunnel mode: When selected,
hev-socks5-tunnelreads the Android VPN file descriptor and forwards traffic to Xray through its local SOCKS5 inbound. - Benchmark & Profiling: For detailed throughput benchmarks and resource profiling results on Android devices, see Android TUN Benchmark Report.
The fork includes several configuration-level optimizations and Android-specific adjustments.
- Hybrid domain matcher: Changes
domainMatcherfrommphtohybridto balance memory usage and domain lookup performance. - DoH bootstrap configuration: Adds static host mappings for matching AliDNS DoH hostnames to avoid DNS bootstrap dependencies for those endpoints.
- Listen address normalization: Converts wildcard listen addresses such as
::and0.0.0.0to127.0.0.1where required by the Android execution environment. - Dashboard latency display: The dashboard shows the TCP handshake time to each outbound's server endpoint. Endpoints are parsed from the configuration: vless and vmess use
settings.vnext[0], while trojan, shadowsocks, HTTP, and SOCKS usesettings.servers[0]. Probes run once when the dashboard is shown and can also be started manually. UDP-only protocols such as WireGuard and Hysteria2, QUIC transports, and private, loopback, or link-local IP literals are skipped. The result measures the network path from the device to the node and does not measure Xray processing time. Unreachable nodes are marked as failed.
Complete Xray-core configuration files can be imported without requiring users to manually remove every desktop-specific setting. Before execution, the imported configuration passes through an Android-specific sanitization pipeline.
The pipeline currently handles the following cases:
- Windows process rules: Removes Windows-specific executable paths such as
chrome.exefromrouting.rulesand removes rules that become invalid as a result. - TUN inbounds: When VPN and Xray TUN mode are enabled, keeps a
protocol: tuninbound, supplies an Android-compatible name, and removes desktop automatic-routing fields. In Hev mode, or when VPN is disabled, removesprotocol: tuninbounds. - File-based logging: Removes filesystem paths configured through the
accessanderrorlogging fields where required to avoid Android filesystem permission errors. - Listen addresses: Normalizes
::and0.0.0.0to127.0.0.1where required by the Android execution environment. - Sniffing configuration: Preserves supported sniffing-related settings, including
destOverride, when sanitizing the configuration.
The sanitization pipeline is intentionally one-way: imported configuration data is transformed into an Android-compatible configuration before being passed to the core.
SimpleXray provides a LogLevel preference with the following options:
AutoDebugInfoWarningErrorNone
The selected log level is applied to the imported configuration during the sanitization process. File-based access and error logging paths are removed where necessary to avoid filesystem permission issues on Android.
The native build system has been migrated from the legacy Android NDK build system to CMake.
- CMake: Uses
CMakeLists.txtinstead ofAndroid.mk/ndkBuild. - Android 16 KB page alignment: The native build configuration includes support for Android devices using 16 KB memory page sizes.
- Gradle Wrapper: Updated to
v9.7.0. - Android Gradle Plugin: Uses
v9.3.1. - Version Catalogs: Project dependencies are managed through Gradle Version Catalogs.
- Plugins DSL: Gradle plugins are configured through the Plugins DSL.
- Serialization:
Gsonhas been replaced withkotlinx.serializationfor type-safe serialization and deserialization.
The following environment is required to build the project:
- Android 14 (API level 34) or later.
- Android SDK with Build Tools and Platform SDK for the configured target SDK (
36). - Android NDK (see
version.propertiesfor the recommendedNDK_VERSION). - Zig
0.16.0(required to build the SimpleTUN Android native library). - CMake 3.22.1 or higher.
- JDK 21.
- Go (for cross-compiling Xray-core, see
version.propertiesfor the recommendedGO_VERSION). - Git with submodule support.
The project uses Gradle Wrapper, so the required Gradle version is obtained automatically from the repository's Gradle Wrapper configuration.
Clone the repository and its submodules:
git clone --recursive https://github.com/ReRokutosei/SimpleXray.git
cd SimpleXrayIf the repository has already been cloned without its submodules, initialize them with:
git submodule update --init --recursiveTo keep the repository lightweight, binary rule files and the Xray-core dynamic library are not tracked by Git and must be prepared before local compilation.
Place the latest geoip.dat and geosite.dat into the app/src/main/assets/ directory:
mkdir -p ./app/src/main/assets/
wget https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat -O ./app/src/main/assets/geoip.dat
wget https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat -O ./app/src/main/assets/geosite.datUse Go and the Android NDK to compile the arm64-v8a core executable, placing it into the JNI libraries directory (ensure the tag matches XRAY_CORE_VERSION in version.properties):
git clone --depth=1 --branch v26.9.30 https://github.com/XTLS/Xray-core.git
cd Xray-core
COMMID=$(git rev-parse HEAD | cut -c 1-7)
export GOOS=android
export CGO_ENABLED=1
export GOARCH=arm64
export CC=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang
go build -o xray -trimpath -buildvcs=false -ldflags="-X github.com/xtls/xray-core/core.build=${COMMID} -s -w -buildid= -checklinkname=0" -v ./main
mkdir -p ../app/src/main/jniLibs/arm64-v8a
mv xray ../app/src/main/jniLibs/arm64-v8a/libxray.soRun the Gradle task directly to produce a debug APK:
./gradlew assembleDebugThe output APK is located at:
app/build/outputs/apk/debug/simplexray-arm64-v8a.apk
The release variant enables resource shrinking and minification, requiring valid V3/V4 APK signing. Create a store.properties file in the project root directory (Alternatively, set the environment variables KEYSTORE_PATH, KEYSTORE_PASSWORD, KEY_ALIAS, and KEY_PASSWORD):
storeFile=/path/to/your/release.jks
storePassword=your_keystore_password
keyAlias=your_key_alias
keyPassword=your_key_passwordThen build the release APK:
./gradlew assembleReleaseThe generated APK is located at:
app/build/outputs/apk/release/simplexray-arm64-v8a.apk
If forking this repository and using GitHub Actions CI for automated builds and releases, note the following requirements:
- Tag Naming Convention: The release workflow (
.github/workflows/release.yml) only triggers on pushing semver tags matchingv*(e.g.v1.5.2). Pushing branches or tags not matching^v[0-9]+\.[0-9]+\.[0-9]+will either not trigger the workflow or fail during tag validation. - Repository Secrets Configuration: You must configure the following Repository Secrets (Settings -> Secrets and variables -> Actions); missing signing credentials will cause the release build step to fail:
SIGNING_KEY: Base64-encoded string of the JKS keystore file (generate viabase64 -w 0 release.jks).KEY_STORE_PASSWORD: Keystore password.KEY_ALIAS: Key alias.KEY_PASSWORD: Private key password.
- Automated Kernel Upgrades:
- The repository features a fully automated source-build pipeline. To upgrade to a newer upstream Xray-core release, you do not need to manually compile or fetch Go binaries: simply edit
XRAY_CORE_VERSIONin the rootversion.properties. - Commit the change and push a valid semver tag (
X.Y.Z). GitHub Actions will automatically check out the matching Xray-core source code, cross-compile the binary, sign the release APK, and publish the GitHub Release.
- The repository features a fully automated source-build pipeline. To upgrade to a newer upstream Xray-core release, you do not need to manually compile or fetch Go binaries: simply edit
SimpleXray incorporates or builds upon the following open-source projects:
compose-miuix-ui— A Jetpack Compose UI component library for Kotlin Multiplatform, inspired by Xiaomi HyperOS / MIUI.Xray-core— The proxy and network core used by SimpleXray.SimpleXray— The upstream Android client on which this fork is based.hev-socks5-tunnel— A SOCKS5 VPN tunnel implementation used for handling Android network traffic.sing-tun— High-performance lightweight user-space network stack and TUN driver implementation for sing-box.
This project uses free icons provided by Magnific. We would like to express our gratitude for the original creator's work:
- Cookie Icons (Special Lineal, Flat, Lineal Color) — Designed by Magnific
For details, please refer to the Privacy Policy and Disclaimer.
By using this application, you acknowledge that you have read and agree to the Privacy Policy and Disclaimer. If you do not agree with either document, please uninstall the application and discontinue its use.
Unless otherwise stated, this project is distributed under the Mozilla Public License 2.0 (MPL-2.0), in accordance with the licensing terms of the upstream project.
See LICENSE for the complete license text.







