Husi is a non-professional and recreational proxy tool integration, aiming at promoting proxy customization.
Is husi not in your language, or the translation is incorrect or incomplete? Get involved in the translations on our Weblate.
In Linux, you can build husi reproducibly for release version.
For this, you should use the same version of JDK, NDK as below. And Go version should as same as version.sh.
git clone https://github.com/xchacha20-poly1305/husi.git --depth=1
cd husi/
./run lib source # Will help you to get submodulesEnvironment:
-
These versions need to apply patch.
Unfold
1.22.5: Apply this patch to
${GOROOT}/src/runtime/cgocall.go1.23.0-1.23.3: Apply this patch to
${GOROOT}.make patch_go12301.23.4: Apply this patch to
$(GOROOT).make patch_go1234 -
Openjdk-21 (Later may OK, too.)
For Android:
make libcore_androidThis will generate composeApp/libs/libcore.aar.
For desktop, build libcore for your host platform:
make libcoreThis will generate composeApp/libs/libcore-desktop-<host-platform>-<host-arch>.jar.
Or for specific targets:
make libcore_desktop DESKTOP_TARGETS=linux/amd64,darwin/arm64If desktop build needs an explicit JNI headers directory, pass JNI_INCLUDE:
make libcore_desktop DESKTOP_TARGETS=linux/amd64 JNI_INCLUDE=/path/to/jniFor Darwin targets on non-Darwin hosts, also pass the macOS SDK explicitly:
make libcore_desktop DESKTOP_TARGETS=darwin/arm64 JNI_INCLUDE=/path/to/jni DARWIN_SDK=/path/to/MacOSX.sdkCommon desktop targets:
linux/amd64linux/arm64darwin/amd64darwin/arm64
For Linux desktop targets, the build includes with_naive_outbound and consults a
cronet-go checkout via build-naive env. If CRONET_GO_ROOT is unset,
libcore/build.sh first checks ../../cronet-go, then falls back to $HOME/cronet-go:
CRONET_GO_ROOT=/path/to/cronet-go make libcoreFor Linux targets, cronet-go exports the naiveproxy cross-toolchain environment directly.
For Darwin targets on a Darwin host, libcore/build.sh keeps with_naive_outbound and derives CC/CXX/CGO_*
from the Chromium clang and hermetic Xcode toolchain inside the cronet-go checkout. If the Darwin SDK/linker tree
is missing, the desktop build fails immediately.
For Darwin targets on non-Darwin hosts, libcore/build.sh uses zig cc / zig c++, requires an explicit macOS SDK
path via DARWIN_SDK or --darwinsdk, exports the matching CGO_* sysroot/library flags, keeps
with_naive_outbound, and does not require a cronet-go checkout, so zig must be available in PATH.
Desktop Gradle builds select composeApp/libs/libcore-desktop-<platform>-<arch>.jar automatically from the current
os.name and os.arch.
You can override it explicitly:
./gradlew -p composeApp run -PdesktopTarget=linux/amd64If the selected jar is missing, the build fails immediately.
If you run libcore/build.sh directly:
--android: build Android only--desktop: build desktop only (default target:host)--android --desktop: build both--jniinclude <path>: pass JNI headers include path to desktopanja bind -target=jvm--darwinsdk <path>: pass a macOS SDK path for Darwin desktop targets on non-Darwin hosts- no platform args: defaults to Android only
If anja is not in GOPATH, it will be automatically downloaded and compiled.
If you don't want to use the same package name, you can run ./run rename target_name.
Environment:
- jdk-21
- ndk 29.0.14206865
If the environment variables $ANDROID_HOME and $ANDROID_NDK_HOME are not set, source
buildScript/init/env_ndk.sh to set them:
source buildScript/init/env_ndk.shThen write the SDK path to local.properties:
echo "sdk.dir=${ANDROID_HOME}" > local.propertiesSigning preparation (optional, it is recommended to sign after compilation): Replace release.keystore with your own
keystore.
echo "KEYSTORE_PASS=" >> local.properties
echo "ALIAS_NAME=" >> local.properties
echo "ALIAS_PASS=" >> local.propertiesDownload geo resource files:
make assetsGenerate open source license metadata:
make aboutlibraries_go
make aboutlibraries_androidThis writes Android metadata to
composeApp/src/androidMain/composeResources/files/aboutlibraries.json.
Compile the release version:
make apkThe APK file will be located in androidApp/build/outputs/apk.
Environment:
- jdk-21
- zig 0.16
Run the desktop application:
make desktopGenerate desktop open source license metadata:
make aboutlibraries_go
make aboutlibraries_desktopThis writes desktop metadata to
composeApp/src/desktopMain/composeResources/files/aboutlibraries.json.
Package a distributable for the current OS:
make desktop_packageThis dispatches to the host-native packaging flow:
- Linux:
make desktop_package_linux - macOS:
make desktop_package_macos - Windows/MSYS:
make desktop_package_windows
Build an uber JAR that runs on system Java (no bundled JRE/runtime image):
make desktop_uberjarOutput directory:
composeApp/build/compose/jars/Run it with system Java (JDK/JRE 21+):
java -jar composeApp/build/compose/jars/fr.husi-<platform>-<arch>-<version>.jarBuild Linux native packages (deb/rpm/pacman) with Java 21 dependency metadata:
make desktop_package_linuxThis command still builds the uber jar first, then packages it with nfpm.
Required host tools: zig, git, nfpm.
Package timestamps are derived from git tag v<VERSION_NAME> from husi.properties,
not from local build time.
Default output directory:
composeApp/build/compose/packages/linux/You can select target formats:
make desktop_package_linux LINUX_PACKAGE_FORMATS=deb,pacmanLinux desktop data directory is $XDG_CONFIG_HOME/husi/ if set, otherwise
$HOME/.config/husi/.
Installed launcher supports user config files in the same Linux config directory:
<config-dir>/husi/desktop-java-opts.conffor JVM options<config-dir>/husi/desktop-app-args.conffor application startup arguments
Linux native packages include a native launcher built with Zig from launcher/.
Build the launcher standalone:
make launcherThe default packaging flow runs make launcher first, then package.sh consumes that binary.
Zig targets musl by default for static linking; no external C toolchain is needed.
Package install scripts call setcap on the launcher so capabilities can be raised to ambient set before starting the JVM.
You can preflight required tooling without producing packages:
./release/linux/package.sh --check-tools --formats deb,rpm,pacmanBuild macOS .dmg packages with system Java runtime dependency:
make desktop_package_macosThis command builds the uber jar first, then packages it into Husi.app and a .dmg image.
The app bundle icon is a checked-in static asset generated from
composeApp/src/commonMain/composeResources/drawable/ic_launcher_foreground.xml,
so packaging no longer builds icons dynamically.
On macOS hosts it uses native tooling: hdiutil.
On Linux hosts it uses xorrisofs and emits a compatibility .dmg
(an ISO9660/HFS hybrid image that macOS can mount). For Linux fallback, DESKTOP_TARGET
is required because the Gradle uber-jar task otherwise defaults to the Linux host target:
make desktop_package_macos DESKTOP_TARGET=darwin/arm64Required host tools:
- Common:
zig,git - macOS host:
hdiutil - Linux fallback:
xorrisofs
Package timestamps are derived from git tag v<VERSION_NAME> from husi.properties,
not from local build time.
Default output directory:
composeApp/build/compose/packages/macos/Installed app bundle uses the same native launcher from launcher/ as Linux packaging.
User config files are created under:
~/Library/Application Support/husi/desktop-java-opts.conffor JVM options~/Library/Application Support/husi/desktop-app-args.conffor application startup arguments
Build Windows portable zip and NSIS installer packages:
make desktop_package_windows DESKTOP_TARGET=windows/amd64This command builds the uber jar first, then packages it with the same Zig launcher used by Linux and macOS. Required host tools:
ziggitpython3makensis(NSIS)
Default output directory:
composeApp/build/compose/packages/windows/Outputs:
<PACKAGE_NAME>-<VERSION_NAME>-windows-<arch>.zip<PACKAGE_NAME>-<VERSION_NAME>-windows-<arch>-installer.exe
The installer is a per-user NSIS installer that installs into %LOCALAPPDATA%\Programs\Husi,
creates a Start Menu shortcut, and registers the configured URL schemes for the current user.
The Windows launcher embeds an application manifest and requests administrator elevation via UAC at launch time.
make plugin PLUGIN=<Plugin name>Plugin name list:
hysteria2juicitynaive( Deprecated. Build official repository directly, please. )mierushadowquic
Requirement: >= Java Runtime 21
No bundled JRE for end users
$ fr.husi --help
Usage: fr.husi [<options>] [<deep-link>]...
Options:
-d, --dir=<path> Data directory
-l, --log-level=<int> Log level override (0-6)
-m, --many Ignore exist instance
-b, --background Start without opening the main window
-h, --help Show this message and exit
Arguments:
<deep-link> Deep linksURLs to import.
Husi can generate and use GeoIP rule-set assets derived from MaxMind GeoLite2 data. GeoLite2 data is created by MaxMind and is subject to the GeoLite2 End User License Agreement and related attribution and update requirements.
Third-party mirrors or re-published GeoLite2 database files do not grant additional rights beyond MaxMind's terms. If you build, redistribute, or use Husi with generated GeoIP assets, you are responsible for ensuring that your use and redistribution of those assets complies with the applicable MaxMind license terms.
- SagerNet/sing-box
- shadowsocks/shadowsocks-android
- SagerNet/SagerNet
- XTLS/AnXray
- MatsuriDayo/NekoBoxForAndroid
- SagerNet/sing-box-for-android
- AntiNeko/CatBoxForAndroid
- MetaCubeX/ClashMetaForAndroid
- dyhkwong/Exclave
- chen08209/FlClash
- RikkaApps/RikkaX
Developing