| Feature | Description |
|---|---|
| Multi-protocol | Single client for VMess, VLESS, Trojan, Shadowsocks, TUIC, Hysteria, WireGuard, HTTP/SOCKS, SSH, TUN mode. |
| sing-box kernel | High-performance core with gVisor, QUIC, UTLS, Clash API, and conntrack support. |
| Professional UX | Material Design interface with themed styling, config editor, and profile management. |
| Privacy first | No telemetry, no ads — all connectivity is explicit and user-controlled. |
| Multi-ABI | Optimized builds for armeabi-v7a, arm64-v8a. |
| Layer | Technology |
|---|---|
| Frontend | Android, Kotlin, Material Design |
| Networking | sing-box, libcore (Go bindings) |
| Native build | Android NDK, Go 1.25, gomobile toolchain |
| Build system | Gradle (Kotlin DSL), buildSrc |
| CI/CD | GitHub Actions (Preview & Release) |
| Tooling | Prettier, EditorConfig, Husky + lint-staged, Dependabot |
BITS-Box/
├── app/ # Android application (Kotlin, UI, services)
│ ├── src/main/java/ # Application source code
│ ├── src/main/res/ # Resources (layouts, strings, drawables)
│ ├── libs/ # Prebuilt bitscore.aar (generated)
│ └── build.gradle.kts # Module build script
├── libcore/ # Go bindings shared with upstream sing-box
├── buildScript/ # Native build & CI scripts (Go, Android, assets)
├── buildSrc/ # Gradle build logic (flavors, metadata, signing, APK naming)
├── .github/
│ ├── workflows/ # CI/CD workflows (preview, release)
│ └── dependabot.yml # Automated dependency updates
├── .husky/ # Git hooks (pre-commit, pre-push)
├── gradle/ # Gradle wrapper
├── build.gradle.kts # Top-level Gradle build script
├── settings.gradle.kts # Gradle module settings
├── bitsbox.properties # Build metadata (version, package name)
├── .prettierrc.json # Code formatter config
├── .prettierignore # Prettier ignore patterns
├── .editorconfig # Editor style config
├── .lintstagedrc.json # Lint-staged config
├── .npmrc # Node package manager config
├── package.json # Formatter & hooks tooling
├── gradlew # Gradle wrapper script (Unix)
├── gradlew.bat # Gradle wrapper script (Windows)
├── lint.xml # Android lint config
└── run # Build helper CLI
| Tool | Version |
|---|---|
| JDK | 21 (pinned; JDK 17 also accepted for Gradle) |
| Android SDK | platforms;android-37, build-tools;37.0.0 |
| Android NDK | 29.0.14206865 |
| Go | 1.25+ (go.mod requires 1.25.0) |
| Node.js | 20+ (optional, for formatter & hooks) |
| pnpm | 10+ (optional, for formatter & hooks) |
# 0. Install formatter & hooks (optional, for code style)
pnpm install
# 1. Fetch pinned external sources + init gomobile toolchain
./run lib core init
# 2. Build native core library (bitscore.aar)
./run lib core build
# 3. Download runtime assets (GeoIP / GeoSite releases)
./run lib assets
# 4. Build APK
make debug-oss # debug, unsigned
make release-oss # release, unsigned (signed with keystore if configured)Artifacts are written to app/build/outputs/apk/.
The project has three product flavors — oss (default, FOSS), play (Google Play, AAB via bundlePlayRelease), and preview (preview channel, what the Preview CI workflow builds). Swap the suffix on any Make target, e.g. make debug-play, make release-preview, or build all with make debug-all / make release-all.
make build-full # clean → fetch sources → init → build libcore → assets → release APKOr using the CLI helper directly:
./run lib core init # fetch sources + gomobile init
./run lib core build # build bitscore.aar
./run lib assets # download GeoIP/GeoSite
./gradlew assembleOssRelease # build APK| Command | Description |
|---|---|
make debug-oss |
Build debug APK (oss flavor) |
make release-oss |
Build release APK (oss) |
make bundle-play |
Build Play AAB (bundlePlayRelease) |
make debug-all |
Build all debug flavors |
make release-all |
Build all release flavors |
make build-full |
Full clean build from scratch |
make lint |
Run Android lint |
make format |
Format all files (Prettier, via Makefile) |
make format-check |
Check formatting (Makefile) |
make check |
format-check + KSP + AAR metadata |
make wrapper |
Update Gradle wrapper |
make install-hooks |
Install git hooks & formatter deps |
pnpm format |
Format all files with Prettier |
pnpm format:check |
Check formatting without writing |
pnpm check |
Format check + Gradle tasks |
./gradlew tasks --all |
List all Gradle tasks |
- Formatter: Prettier 3 (
prettier --write .) with.prettierrc.json(printWidth: 100, singleQuote, semi, 2 spaces) and.prettierignore(ignoresbuild/,app/libs/,external/,gradle-wrapper.jar, etc.) - EditorConfig:
.editorconfigenforceslf,utf-8,trim_trailing_whitespace,2 spaces(4 for*.kt/*.kts/*.java),tabforMakefile/*.go - Git Hooks: Husky 9 + lint-staged (auto-installed via
prepare):pre-commit:lint-staged→prettier --writefor*.{js,ts,json,css,md,yml,yaml,kt,kts,xml,gradle}pre-push:npm run format:check(formatting must pass)
- Usage:
pnpm install # install formatter & hooks (runs husky prepare)
# or: make install-hooks
pnpm format # manual format (or: make format)
pnpm format:check # CI check (or: make format-check)
# hooks run automatically on `git commit` / `git push`
# skip if needed: HUSKY=0 git commit -m "..."Automated dependency updates via .github/dependabot.yml:
| Ecosystem | Directory | Schedule |
|---|---|---|
github-actions |
/ |
Weekly Monday 02:30 |
gradle |
/ |
Weekly Monday 03:00 |
npm |
/ |
Weekly Monday 03:30 |
- Groups
minor+patchupdates, limits PRs (10 for Actions, 5 for Gradle/npm) - Ignores major bumps for
com.android.tools.build:gradleandkotlin-gradle-plugin - Labels:
dependencies,github-actions/gradle/npm gomod(libcore) is disabled — Go deps use localreplace(../external/sing-box) and are pinned viaCOMMIT_SING_BOX/COMMIT_BITSBOX_COREinbuildScript/lib/core/get_source_env.sh
Provide a keystore via local.properties:
KEYSTORE_PASS=...
ALIAS_NAME=bitsbox
ALIAS_PASS=...Or via the LOCAL_PROPERTIES environment variable (base64-encoded).
| Workflow | Trigger | Output |
|---|---|---|
👁️ Preview Build (preview.yml) |
workflow_dispatch |
Preview APKs (artifact) |
🏷️ Release Build (release.yml) |
workflow_dispatch (with tag, publish, play inputs) |
Signed release APKs + optional GitHub release / Play AAB |
| Input | How obtained | Purpose |
|---|---|---|
external/sing-box |
./run lib core get source clones SagerNet/sing-box @ v1.13.19 |
upstream core module |
external/bits-box-core |
./run lib core get source clones bitscoid/BITS-Box-Core @ pinned commit |
BITS Box Go core module |
gomobile-bits, gobind-bits |
libcore/init.sh clones bitscoid/gomobile |
Android Go binding toolchain |
| GeoIP / GeoSite assets | ./run lib assets downloads the latest minimal variants |
runtime databases |
BITS Box bundles small GeoIP/GeoSite databases at build time and can refresh or upgrade them in-app without reinstalling the APK.
| Variant | GeoSite categories | GeoIP | Bundled in APK | Notes |
|---|---|---|---|---|
| Minimal (default) | id, rule-ads, rule-indo |
id |
✅ ~56 KB | Enough for the default profile rules |
| Full | All v2fly categories + extra lists | All countries | ❌ on demand | Needed for any rule beyond the defaults |
The active variant is selected in Settings → Rule Assets Variant. The Minimal databases are packed into the APK (assets/sing-box/); the Full databases are downloaded from the BITS-GeoIP / BITS-GeoSite releases the first time you choose the Full variant.
On Settings → Manage Route Assets each database shows its local version and an Update button. Updates pull the latest GitHub release for the currently selected variant and always store the file under its canonical name (geoip.db / geosite.db), so the core engine never needs to know which variant is in use.
GeoSite rules use geosite:<category>; GeoIP rules use geoip:<country-code> (ISO 3166-1 alpha-2, e.g. id, sg, us, cn).
Platform / brand categories: apple, google, google-play, facebook, instagram, twitter, telegram, netflix, youtube, spotify, discord, steam, epicgames, microsoft, amazon, cloudflare, github, openai, ...
Grouped category-* categories:
| Category | Covers |
|---|---|
category-ads-all |
Ad / tracking domains |
category-ai-!cn, category-ai-cn |
AI services (non-CN / CN) |
category-games-!cn, category-games-cn |
Gaming |
category-media-!cn, category-media-cn |
Streaming & media |
category-social-media-!cn, -cn |
Social media |
category-cryptocurrency |
Crypto services |
category-communication |
Messaging / comms |
category-porn |
Adult content |
category-ip-geo-detect |
IP geolocation detection |
geolocation-!cn, geolocation-cn |
All domains (non-CN / CN) |
Extra lists: oisd-full, oisd-small, oisd-nsfw, d3ward, rule-ads, antiscam, rule-doh, rule-gaming, rule-indo, rule-playstore, rule-sosmed, rule-streaming, rule-umum, rule-ipcheck, rule-speedtest, videoconference, rule-malicious, urltest.
| Pattern | Effect |
|---|---|
geosite:rule-ads |
Match ad domains (block) |
geosite:rule-indo |
Match Indonesian domains (bypass) |
geoip:id |
Match Indonesian IPs (bypass) |
geosite:netflix |
Match Netflix domains (proxy) |
port=443, network=udp |
Match QUIC traffic (block) |
Note: with the Minimal variant only
id,rule-ads,rule-indoandgeoip:idare available. Rules referencing other categories are silently skipped. Choose Full + Update to enable all categories.
Default rules for a new profile:
1. Block QUIC port = 443, network = udp → block
2. Block ads geosite:rule-ads → block
3. Bypass Indonesia geosite:rule-indo → direct
4. Bypass Indonesia IP geoip:id → direct
| Item | Value |
|---|---|
| App name | BITS Box |
| Package ID | id.bits.box |
| Deep link scheme | bitsbox:// |
| Website | https://bits.co.id |
| Support | admin@bits.co.id |
| Privacy policy | https://bits.co.id/privacy |
| Terms of service | https://bits.co.id/terms |
| Repository | Purpose |
|---|---|
| BITS-Box | This application |
| BITS-Box-Core | Core engine library (Go) |
| sing-box | sing-box kernel |
| BITS-GeoIP | GeoIP database releases |
| BITS-GeoSite | GeoSite database releases |
This project is free software, released under the GNU General Public License v3 (or later). See LICENSE for the full text.
The project is a fork of the SagerNet / Matsuri projects (NekoBoxForAndroid), and all upstream copyright notices and licenses are preserved. Contribution, fork, and redistribution must comply with the GPLv3 license and retain the original attribution.