Русский | Deutsch | Italiano | 中文 | 日本語
A extensively modified and feature-rich fork of Reticulum MeshChat by Liam Cottle.
This project is independent from the original Reticulum MeshChat project and is not affiliated with it.
CHANGELOG.mddonate.md (Donation)f489752fbef161c64d65e385a4e9fc74rngit NomadNet Node: 132f67e79d9b24aad014e93015fb858f:/page/index.mu
rngit: git clone rns://06a54b505bb67b25ef3f8097e8001edc/public/MeshChatX
MeshChatX NomadNet Node: c10d80b1a42fa958c37a6cc30dc04f53:/page/index.mu
>=3.11 (from pyproject.toml)>=24 (from package.json engines)11.1.2 (from package.json packageManager)Taskfile.yml and CI workflows)Browser Versions Required:
Safari 16.4 or later, Chrome 111 or later, Firefox 128 or later (bundled web UI).
task install
task lint:all
task test:all
task build:all
Use the method that matches your environment and packaging preference.
| Method | Includes frontend assets | Architectures | Best for |
|---|---|---|---|
| Docker image | Yes | linux/amd64, linux/arm64 |
Fastest setup on Linux servers/hosts |
Python wheel (.whl) |
Yes | Any Python-supported architecture | Headless/web-server install without Node build |
| Linux AppImage | Yes | x64, arm64 |
Portable desktop use |
Debian package (.deb) |
Yes | x64, arm64 |
Debian/Ubuntu installs |
RPM package (.rpm) |
Yes | CI-runner dependent for published artifact | Fedora/RHEL/openSUSE style systems |
| From source | Built locally | Host architecture | Development and custom builds |
Notes:
dev or master, SLSA, draft release) in one run via .github/workflows/build-release.yml; the container image via .github/workflows/docker.yml. Branch and PR Android CI stays in .github/workflows/android-build.yml.x64 and arm64 AppImage + DEB are built on GitHub; RPM is attempted and uploaded when produced.quad4io/meshchatxghcr.io/quad4-software/meshchatxdocker compose up -d
docker run -d --name reticulum-meshchatx \
--restart unless-stopped \
--security-opt no-new-privileges:true \
-p 127.0.0.1:8000:8000 \
-v meshchatx-config:/config \
ghcr.io/quad4-software/meshchatx:latest
You can substitute quad4io/meshchatx:latest for the image if you prefer Docker Hub.
Default compose file maps:
127.0.0.1:8000 on host -> container port 8000meshchatx-config -> /config for persistence (works with the image meshchat user, UID 1000, without bind-mount permission fixes)Optional: bind mount a host directory instead
If you want data under a host path (for example ./meshchat-config), replace the volume line with -v "$(pwd)/meshchat-config:/config" (Compose: change the service volumes entry to that bind path). The container runs as UID 1000; the host directory must be writable by that uid (typical fix: sudo chown -R 1000:1000 ./meshchat-config). If the directory is empty on first run, create it first so Docker does not create it as root-only.
Inspect or reset the named volume
docker volume inspect meshchatx-config
# remove container and delete persisted data (destructive)
docker rm -f reticulum-meshchatx
docker volume rm meshchatx-config
ReticulumMeshChatX-v<version>-linux-<arch>.AppImage from releases.chmod +x ./ReticulumMeshChatX-v*-linux-*.AppImage
./ReticulumMeshChatX-v*-linux-*.AppImage
.deb (x64/arm64)ReticulumMeshChatX-v<version>-linux-<arch>.deb.sudo apt install ./ReticulumMeshChatX-v*-linux-*.deb
ReticulumMeshChatX-v<version>-linux-<arch>.rpm if present in the release.sudo rpm -Uvh ./ReticulumMeshChatX-v*-linux-*.rpm
.whl)Release wheels include the built web assets.
pip install ./reticulum_meshchatx-*-py3-none-any.whl
meshchatx --headless
pipx is also supported:
pipx install ./reticulum_meshchatx-*-py3-none-any.whl
Use this when developing or when you need a local custom build.
git clone https://github.com/Quad4-Software/MeshChatX.git
cd MeshChatX
corepack enable
pnpm config set verify-store-integrity true
pnpm install --frozen-lockfile
pip install "uv==0.11.15"
uv lock --check
uv sync --group dev
pnpm run build-frontend
uv run python -m meshchatx.meshchat --headless --host 127.0.0.1
Notes on the install commands above:
pnpm install --frozen-lockfile refuses to update pnpm-lock.yaml and fails if the lockfile does not match package.json. This is what blocks an unexpected upstream version from being silently pulled in.verify-store-integrity=true is also set in the project pnpm-workspace.yaml; the explicit pnpm config set line above just hardens the user-level config too.preinstall/postinstall) are blocked by default in pnpm v11+. Only the packages listed under allowBuilds in pnpm-workspace.yaml are allowed to run install scripts (currently electron, electron-winstaller, esbuild).uv lock --check fails fast if uv.lock is out of sync with pyproject.toml; uv sync then resolves only from the lockfile.pip install "uv==0.11.15" to match what CI uses.If you intentionally want to update dependencies, run pnpm update / uv lock in a dedicated commit and review the resulting lockfile diff before pushing.
To run the native meshchatx binary (alias: meshchat) with extra filesystem isolation, you can use Firejail or Bubblewrap (bwrap) while keeping normal network access for Reticulum and the web UI. Full examples (pip/pipx, Poetry, USB serial notes) are in:
The same page appears in the in-app Documentation list (MeshChatX docs) when served from the bundled or synced meshchatx-docs files.
The emoji picker renders standard Unicode emoji using your system fonts (Electron/Chromium). If emoji show as empty squares (“tofu”), install a color emoji package and restart the app.
| Family (examples) | Package |
|---|---|
| Arch Linux, Artix, Manjaro | noto-fonts-emoji (sudo pacman -S noto-fonts-emoji) |
| Debian, Ubuntu | fonts-noto-color-emoji (sudo apt install fonts-noto-color-emoji) |
| Fedora | google-noto-emoji-color-fonts |
After installing, run fc-cache -fv if glyphs still fail until the next login. Optional: noto-fonts for broader symbol coverage on minimal installs.
Calls and voice attachments use the microphone through Chromium inside the desktop app. If the UI shows no access or getUserMedia fails, check Windows privacy first (this is a frequent cause for “classic” Win32 apps, including Electron):
ms-settings:privacy-microphone, press Enter.Also confirm the app is not muted in Settings → System → Sound and that a working input device is selected.
MeshChatX supports two levels of offline building:
make install once and have node_modules/, .venv/, and local caches.Set MESHCHATX_OFFLINE_BUILD=1 before running any build command. This skips all network fetches (micron-parser-go WASM, Reticulum manual, repository wheels) and runs package managers in offline mode. If a required cached asset is missing, the build fails with a clear error instead of hanging.
# Install dependencies offline (requires populated pnpm store and uv cache)
MESHCHATX_OFFLINE_BUILD=1 make install
# Build frontend + backend offline
MESHCHATX_OFFLINE_BUILD=1 pnpm run build:offline
# Build Linux desktop packages offline
MESHCHATX_OFFLINE_BUILD=1 pnpm run dist:linux:offline
# Android Gradle also respects the flag
MESHCHATX_OFFLINE_BUILD=1 ./gradlew :app:assembleRelease
Note: Cached offline mode only skips build-time network access. The first
make installmust be run online (or with pre-populated caches) so thatpnpmanduvhave the packages available locally.
For machines with no internet access at all, create an offline bundle on a networked machine and transfer it.
On the online machine:
# Create the bundle (includes node_modules, Python wheels, and tooling caches)
pnpm run bundle:offline
# Optional: also pre-download packaging tools (appimagetool, etc.)
bash scripts/create-offline-bundle.sh --warm-packaging
# Transfer the bundle to your air-gapped machine
tar czf meshchatx-offline-linux-x64.tar.gz -C vendor/offline meshchatx-offline-bundle-*/
On the air-gapped machine:
# Extract the bundle into the project
tar xzf meshchatx-offline-linux-x64.tar.gz
# Install from the bundle (extracts node_modules and sets up caches)
bash scripts/install-offline.sh
# Build completely offline
MESHCHATX_OFFLINE_BUILD=1 make build
# Or package offline
MESHCHATX_OFFLINE_BUILD=1 pnpm run dist:linux
The bundle is platform-specific because it contains native binaries (Electron, esbuild, etc.). Create it on the same OS/architecture as the air-gapped build host.
Prerequisites on the air-gapped machine: node, pnpm, uv, and python3 must be installed (the bundle provides all dependencies and caches, not the toolchain itself).
Android builds: The offline bundle does not include Android Chaquopy wheels. Build those separately on an online machine (
bash scripts/build-android-wheels-local.sh) and copyandroid/vendor/to the air-gapped host alongside the project. Then run Gradle withMESHCHATX_OFFLINE_BUILD=1.
These scripts are defined in package.json and Taskfile.yml.
pnpm run dist:linux-x64
pnpm run dist:linux-arm64
pnpm run dist:rpm
Or through Task:
task dist:fe:rpm
Dockerfile.build runs the same shell-driven steps CI uses (Poetry, pnpm, task, packaging APT deps). It is oriented toward linux/amd64 (NodeSource amd64 tarball, Task amd64 binary). Default target is everything; override with a build arg.
Targets for MESHCHATX_BUILD_TARGETS: all (default), wheel, or electron (AppImage + deb for x64 and arm64, best-effort RPM, no wheel).
Build:
docker build -f Dockerfile.build -t meshchatx-build:local .
Build only a wheel:
docker build -f Dockerfile.build --build-arg MESHCHATX_BUILD_TARGETS=wheel -t meshchatx-build:wheel .
Copy /artifacts from the finished image to the host:
cid=$(docker create meshchatx-build:local)
docker cp "${cid}:/artifacts" ./meshchatx-artifacts
docker rm "${cid}"
amd64, `arm6$ claude mcp add MeshChatX \
-- python -m otcore.mcp_server <graph>