Run Levix directly on your Android phone as an autonomous background companion — no VPS, no Termux at runtime, no cloud server, and no subscription fees.
Levix for Android packages the complete Levix stack into a standalone Android APK:
- Node.js 24 LTS compiled for Android Bionic (ARM64 and ARMv7)
- SQLite datastore powered by Node's built-in
node:sqlite - Baileys v7 WhatsApp protocol engine with local LID mapping
- AI Agent with multi-provider support (Gemini, OpenAI, Anthropic)
- All 55+ Commands & group moderation tools
- Embedded FFmpeg for native WhatsApp voice notes (
!tts) and video/image preview thumbnails - Local Web Control Panel accessible directly from the app's built-in WebView or your mobile browser (
http://127.0.0.1:3001)
| Requirement | Specification |
|---|---|
| Architecture | ARM64 (levix-android-arm64.apk — almost all phones since 2016) or ARMv7 32-bit (levix-android-armv7.apk — remaining 32-bit-only devices). |
| Android Version | Android 10 or newer (API level 29+; the app targets API 36). |
| Free Storage | ~400 MB (APK ~100–110 MB per ABI + unpacked app bundle + SQLite database). |
| WhatsApp Account | An active WhatsApp account to link with via pairing code or QR. |
- Go to the Levix Releases page on GitHub.
- Download the APK that matches your device:
levix-android-arm64.apk— 64-bit devices (almost all phones since 2016).levix-android-armv7.apk— 32-bit-only devices.- Not sure? Install the AIDA64 app or check your phone's specs; if it says
arm64-v8a/aarch64/ "64-bit", use the arm64 build.
- Open the downloaded APK on your device and tap Install.
- If prompted by Android, enable "Install unknown apps" for your browser or file manager.
- Open the Levix Host app from your home screen or app drawer.
- Launch Levix Host. The first launch opens a short guide — five steps, each with a picture of the screen it is describing — and Skip leaves it at any point. Show guide again on the home screen brings it back.
- Tap the big circle (Start Assistant).
- When prompted, grant Notification permissions so the host can maintain an ongoing foreground service and keep the bot running while the screen is off.
- When prompted, tap Allow to disable battery optimization for Levix.
The circle becomes a progress state while the engine starts. Once ready, Connect WhatsApp opens the secure Connection workflow. Engine readiness and WhatsApp connectivity are shown separately, and the ongoing notification reports the session state.
- Tap Connect WhatsApp in the app to open the panel on Connection. Once fully connected, the home action becomes Open Control Panel.
- The initial setup screen will appear (
/setup). Choose a secure master password for your web control panel and submit.
Because you are running the bot on a phone, scanning a QR code on the same screen is difficult. Levix provides a direct Pairing Code option:
- In the Web Control Panel, navigate to Connection.
- Select Pairing Code (selected by default on Android).
- Enter your WhatsApp phone number with international country code (e.g.
201012345678— do not include+,-, or leading0). - Tap Request Pairing Code.
- An 8-character code will be generated (e.g.,
ABCD-1234). - On your phone, open WhatsApp:
- Tap Settings (or the three dots menu
⋮). - Tap Linked Devices.
- Tap Link a Device.
- Tap Link with phone number instead at the bottom of the screen.
- Enter the 8-character code displayed in your Levix panel.
- Tap Settings (or the three dots menu
- WhatsApp will complete the handshake. Within a few seconds, the connection status will turn green: Connected.
- Header — the Levix mark and app name stay on the left; the language and appearance controls stay on the right in both languages. Tap the globe to switch العربية / English, and the sun/moon to switch Light / Dark.
- Start Assistant — the large power circle is the primary action while stopped. Startup shows progress, pairing offers Connect WhatsApp, and a connected assistant shows a compact ready card with Open Control Panel. Stop Assistant is a separate action. Contextual guidance also explains reconnecting, offline pauses, expired sessions, and engine errors.
- Battery Guard — appears below activation guidance. Restrictions show a warning and Enable Battery Guard; an exemption shows a compact healthy card. Android or device restrictions can still interrupt background operation.
- WhatsApp & Bot Engine tiles — tap the WhatsApp tile for the read-only connection sheet: state, since when, error, network and engine.
- Media Hub — browses the statuses and WhatsApp media stored on this phone.
- Show guide again — reopens the five-step guide, with the same pictures and steps as the first launch.
- Diagnostics — tap the card for Save & open (writes
Downloads/Levix/levix-host-<timestamp>.logand opens it in your viewer) or Share logs (Android's share sheet). Nothing leaves the phone until you pick one.
Android manufacturers apply aggressive battery-saving algorithms that kill background processes. To keep Levix connected 24/7 with the screen locked:
- Open Settings → Apps → Manage apps → Levix.
- Enable Autostart (or Background autostart).
- Tap Battery saver → select No restrictions.
- Open the Android Recents screen (app switcher), press and hold the Levix card, and tap the Lock icon to lock it in memory.
- Open Settings → Apps → Levix.
- Tap Battery → select Unrestricted.
- Open Settings → Battery → Background usage limits → Never sleeping apps → tap
+and add Levix.
- Open Settings → Apps → App management → Levix.
- Tap Battery usage → enable:
- Allow foreground activity
- Allow background activity
- Allow auto-launch
- Open Settings → Apps → Levix.
- Tap App battery usage (or Battery) → select Unrestricted.
Levix includes intelligent network and connection lifecycle handling:
- Ongoing Foreground Notification:
The notification drawer displays the live state of both the host service and WhatsApp:
WhatsApp: ConnectedWhatsApp: ⏳ Reconnecting (code: reason)WhatsApp: ⏸️ Paused (No Internet)
- Offline Alerts (
levix-alerts): If your phone loses Wi-Fi and mobile data or WhatsApp disconnects, Levix posts a high-priority alert. When internet returns, the alert automatically dismisses. - Smart Pause & Auto-Reconnect: When you enter airplane mode or lose connectivity, Levix immediately pauses retries instead of burning your 5 retry attempts. As soon as connectivity is restored, Levix resets the retry counter and automatically reconnects within 2 seconds.
Open Media Hub from the native host screen to browse WhatsApp and WhatsApp Business statuses, photos, videos, voice notes, audio, documents, and stickers. Search, filter, favorite, share, and save copies to user-visible Levix folders. Storage Insights shows local totals and large files. Only copies saved by Levix can be deleted in the hub.
The header has compact source, media-type, filter, sort, and Storage Insights icons. Tap a choice icon to see its options. Long-press a card to select it; its border covers the whole preview. The selection bar keeps Save, Share, and Delete as icons, with Select all, Favorite, sticker actions, and Clear selection in the three-dot menu.
The hub asks for media permission when you open it, after an explanation. Android 14's selected-media permission shows only the items you selected; you can select more or allow full access in system settings. Hidden .Statuses folders and some documents may not appear in MediaStore. In that case, use Enable status access to grant read-only access to the WhatsApp Media folder through Android's folder picker. Levix remembers the grant and asks again only if access is removed. Media Hub never uploads files, names, thumbnails, or folder details.
Levix bundles a native build of FFmpeg (libffmpeg.so — ARM64 or ARMv7, matching the APK) inside the APK, compiled from source with NDK r29 so it is safe on 16 KB-page devices.
- Voice Notes (
!tts): The Text-to-Speech command automatically transcodes Google TTS MP3 audio into true WhatsApp PTT voice notes (audio/ogg; codecs=opus). - Media Previews: Video and picture thumbnails (
jpegThumbnail) are generated locally on the phone before sending, ensuring crisp previews in chat bubbles and quotes. - Stickers: The WebP encode, animation and muxing that Sticker Studio needs (see below).
- No external packages or Termux setup are required.
Sticker Studio is the panel's sticker screen. It is reached from the native side rather than opened by hand, because the panel runs in a WebView with no file picker of its own and no way to reach a content:// URI belonging to the Media Hub.
Any single item in Media Hub can be turned into a sticker, in two places:
- the viewer, on the action row under the picture — hidden for items with no sticker form;
- the selection bar’s three-dot menu, on Make sticker — offered only when exactly one stickerable file is selected, since Sticker Studio takes one file at a time.
The label follows the file:
| Label | When | What the panel does |
|---|---|---|
| Make sticker | an image, GIF or video | opens the converter: trim, frame, and re-encode to WebP |
| Add to stickers | a WhatsApp sticker (.webp) |
keeps the file as it is and only adds it to your library |
Voice notes, audio and documents get no action at all — they have no sticker form, so nothing is shown rather than something that would always refuse.
Tapping either one opens the panel on its Sticker Studio screen. Nothing is read on the phone at that moment: the app records the URI it already has permission to read, and the panel picks it up from there. If the file is over the cap, or Android never reported its size, you get a message instead of a screen.
The Media Hub offers files up to 16 MB, mirroring Sticker Studio's server upload limit (src/stickers/limits.cjs, UPLOAD_MAX_BYTES). It still rejects items with unknown size before opening the panel. This is an offer rule, not a WebView bridge limit: Android streams the selected content:// URI to Node over the local unix socket, and Node enforces the upload limit again while reading. The panel receives a short-lived token and a loopback preview URL. A preview GET opens the URI as a stream in shouldInterceptRequest; no source file is copied into the bridge.
| Method | What it does |
|---|---|
takePendingSticker() |
One-shot Media Hub hand-off; returns intent, token, url, name, mime, and size, with no bytes |
pickStickerSource(callId) |
Opens Android's image/video picker, then returns source metadata through window.__levixHostDone |
uploadSource(callId, token, fileName, maxBytes) |
Streams the selected URI to the local Sticker Studio upload route |
exportFile(callId, action, path, method, jsonBody, fileName, mime) |
Streams an export from Node to the share cache or Downloads/Levix |
cancel(callId) |
Closes an active transfer and returns a cancelled result |
The asynchronous methods acknowledge immediately and deliver small JSON through window.__levixHostDone(callId, result). Tokens expire after one hour; the activity keeps at most eight and clears them when it closes. Share files are written to cache/shared/ and swept after 24 hours. Save writes a pending MediaStore Downloads row and publishes it only after the stream finishes. Both export destinations enforce the Sticker Studio MIME allowlist and sanitize the file name.
The ordinary request() bridge still carries other panel POST bodies; the small settings JSON export still uses saveExportFile().
Re-editing a sticker from the library creates its upload on the server, so its preview Blob is never posted through the bridge.
android/scripts/build-ffmpeg-android.sh builds libwebp 1.6.0 (with a pinned SHA-256) and adds these components:
| Kind | Components | Why |
|---|---|---|
| libraries | libwebp + libwebpmux + libsharpyuv |
WebP encode/decode, animation, and muxing; libwebp's own sharp/colour-space helpers |
| encoders | libwebp, libwebp_anim, rawvideo |
still stickers, animated stickers, and raw frames |
| demuxers | rawvideo, image_gif_pipe |
reading GIF frames to animate them |
| muxers | webp, rawvideo |
writing a .webp container |
Static and PIC, CC/AR/RANLIB supplied by the cross toolchain, so the result stays position-independent and safe on 16 KB-page devices. The ARM64 binary grows by roughly 5% against the build without it.
The filters FFmpeg already enables at defaults are what the studio's own pipeline needs — pad, fps, scale, crop, trim, transpose, split, colorkey, overlay, palettegen, paletteuse — so nothing was added or removed there.
All state is stored in your device's private app storage:
/data/data/net.leviro.levix/files/data/
├── levix.db # SQLite database (settings, auth creds, notes, schedules)
├── logs/ # Bot activity logs
└── memory/ # AI long-term memory markdown files
To back up your configuration and WhatsApp session:
- Via ADB (No Root Required):
adb backup -f levix-backup.ab net.leviro.levix
- Via Root / File Manager:
Copy
/data/data/net.leviro.levix/files/data/levix.dbto your SD card or cloud storage.
To update Levix to a newer version:
- Download the new APK from Releases —
levix-android-arm64.apkorlevix-android-armv7.apk, whichever you installed before. - Install it directly over the existing app.
- Your database, WhatsApp pairing, settings, and passwords will remain completely intact.
- On first launch after updating, Levix automatically detects the version upgrade and refreshes the application bundle in the background.
If you prefer to compile Levix Host from source:
- JDK 17 & Android SDK 36 (
$ANDROID_HOMEconfigured) - Node.js 24+ on your development machine
- Tools:
zip,unzip,rsync,curl,python3,dpkg-deb(for extracting the runtime packages),makeandpkg-config(for building FFmpeg)
Download and unpack the Node.js 24 binaries for Android and build FFmpeg for each ABI (the first run downloads NDK r29 unless $ANDROID_HOME/ndk/29.0.14206865 exists):
android/scripts/fetch-node-android.sh # both ABIs
android/scripts/fetch-node-android.sh arm64-v8a # one ABI onlyThe script verifies every 64-bit ELF is safe on 16 KB-page devices — 16 KB aligned, RELRO not sharing a page with writable data, built with NDK r28+ — as Google Play requires for apps targeting API 35+, and fails the build otherwise.
Each staged runtime is stamped (~/.cache/levix-android/node-runtime/<abi>/.levix-stamp) with the sha256 prefixes of build-ffmpeg-android.sh and fetch-node-android.sh. Gradle recomputes the stamp and refuses to package a runtime staged from older recipes — or one whose libffmpeg.so lacks the libwebp/libwebp_anim sticker encoders — and prints the command that refreshes it (LEVIX_ANDROID_ABIS=<abi> bash android/scripts/fetch-node-android.sh). Re-run the script whenever either recipe changes; Gradle will not run it for you.
Run Gradle to assemble one APK per ABI:
cd android
./gradlew :app:assembleDebugThe Gradle
stageLevixApptask automatically runsnpm run build:frontendto compile the React dashboard intopublic/dashboard, stages the production server bundle intolevix-app.zip, and embeds it inside the APK assets. Staging fails rather than packaging an APK whose panel would render unstyled: it checks thatpublic/dashboard/index.htmlexists, links a stylesheet, and that every asset it references is present both on disk and insidelevix-app.zip.
The panel's CSS is built for the system WebView, which on the 32-bit (
armeabi-v7a) devices the APK supports is far behind current desktop browsers.frontend/vite.config.tsflattens Tailwind's@layerblocks — a WebView without cascade layers (pre-Chrome 99) drops them wholesale and renders the panel with no styling at all — and downlevelsoklch()through Lightning CSS.
It also re-states Tailwind's
translate/rotate/scaleutilities astransformbehind@supports not (translate: 0px). Those standalone properties need Chrome 104, and a WebView that drops them leaves the mobile sidebar parked over the page (its-translate-x-fullnever moves it off-screen), the settings toggles stuck showing "off", and the RTL icon flips dead. The build fails rather than emit a transform it cannot downlevel, so a Tailwind upgrade that uses a new shape is caught here instead of on someone's phone.
Outputs land in android/app/build/outputs/apk/<buildType>/ as levix-android-arm64.apk and levix-android-armv7.apk.
adb install -r app/build/outputs/apk/debug/levix-android-arm64.apkGoogle Play requires an AAB, not an APK:
cd android
./gradlew :app:stageLevixBundle
# -> app/build/outputs/bundle/release/levix-android.aabThe AAB contains both ABIs; Play generates the right per-device APK from it. Sign with your upload keystore via LEVIX_KEYSTORE_FILE / LEVIX_KEYSTORE_PASSWORD / LEVIX_KEY_ALIAS / LEVIX_KEY_PASSWORD (stageLevixBundle refuses to run without them — Play rejects debug-signed bundles; release APKs from assembleRelease still fall back to the debug keystore for local testing). Before submitting, fill the Play Console Data safety form from PRIVACY.md and host that policy at a public URL.
Levix has no support desk, and nothing about your installation is reported automatically. When something is wrong — or right — the panel is where you say so:
- Tap Open Control Panel in the app.
- Go to Settings → Feedback.
- Pick what it is about (a bug, an idea, a question, or how it is going), write the message, and press Send.
The message goes to the developer directly. What travels with it: your text, the topic, an optional 1–5 rating, an optional way to reach you, one optional file you attach yourself (a screenshot or a log, up to 20 MB), and the Levix version and platform so a bug report says which build it came from. Nothing from WhatsApp is attached — no message, chat, contact, credential or key — and nothing is sent until you press Send. The same form is on the web at levix.leviro.net/feedback if the host will not start at all.
Leave the contact field empty and nothing you send names you; fill it in if you want an answer. For a bug you would rather see tracked in public with logs attached, open a GitHub issue and use Diagnostics → Share logs in the app to attach the host log.
Make sure you enter your phone number with the international country code and without leading zeroes or symbols (e.g. 2010XXXXXXXX for Egypt, 1XXXXXXXXXX for USA). Do not enter 010... or +20....
Make sure the host service is running. Open the Levix Host app and verify the Bot Engine card shows that the engine is operational. If it is stopped, tap the big circle (Start Assistant).
By default, the web panel is bound strictly to 127.0.0.1 (localhost) for mobile security. To access it from a computer on the same network, use ADB port forwarding:
adb forward tcp:3001 tcp:3001Then navigate to http://localhost:3001 in your computer's browser.
Yes — install levix-android-armv7.apk. (Most phones from 2016 onward are 64-bit and should use levix-android-arm64.apk instead; the 64-bit build is the one Google Play serves by default.)
Settings → Feedback in the control panel — see "Sending Feedback & Reaching the Developer" above. It reaches the developer directly, and the app version and platform travel with it so nothing has to be guessed.
Levix is optimized to idle at negligible CPU usage (~0.1% - 0.5% CPU when no messages are being processed). RAM usage typically hovers around 90–140 MB.