XMPP client written in JavaScript that works both in browser and as native app using Tauri.rs https://another.im
  • TypeScript 77.4%
  • Rust 7.4%
  • Kotlin 6.2%
  • Python 4.5%
  • JavaScript 2%
  • Other 2.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-28 00:31:26 +02:00
docker The WebKit smoke runs its screens in as many WebKit processes as the machine has threads and waits for the page instead of the clock (the user, 2026-10-27: "Why the gate is taking too long?"): a dispatcher hands the screens out longest first to SMOKE_JOBS workers, each with its own broadway display, file server and XDG directories, and prints every screen's lines in the list's order; the old sleeps (1.5s, 600ms an action, 50ms a check) became a virtual clock, every page timer stamped with the moment it would have fired and waited for only until that moment comes, plus fetches, finite animations, fonts and two frames after an action, never longer than the old schedule; checks are read until they hold for up to 3s; the storage is emptied before every screen and the first-run delivery sheet taken as seen, which had stood in front of "list header" whenever it ran first; docker/run.sh passes SMOKE_* (SMOKE_ONLY never reached the container), lifts the 2048-task cap and gives /dev/shm 4 GB, without which a dozen windows died of thread exhaustion and SIGBUS. 7,247 checks, ~50 minutes before, about one now. 2026-10-27 22:18:36 +02:00
docs 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
flatpak 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
libtacky@47df7fd7c2 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
src-tauri 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
tools The WebKit smoke checks the menus' final layout of 1a1651da: the account menu is Set status…, My profile, Contacts, a line, Service discovery, Stickers… (Service discovery wears the glass where Account settings wore the cog); the "…" is Settings, Calls, a line, XML console, then New window where windows open and Offline mode; an account's right-click in the switcher has Open in this window and Open in new window alone, and with no windows to open no menu at all, the right-click only closing the switcher; the account's page opens from its row in Settings, Accounts, and on the phone Back leaves Settings under it; the menu's type-ahead "s" goes from Set status… to Service discovery. 7,247 checks, 0 failed. 2026-10-27 22:23:53 +02:00
ui 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
worker Comments and one make message that still pointed at sections the README rewrite (79a35cfb, and f601f059 before it) took away point at where the text lives now: "From this clone" in the Makefile at docs/building.md "In containers", and the missing-archive message at libtacky's docs/building.md "Building"; "Build-time knobs" (add-account.ts, signin-card.ts, edition.test.ts) at the build knobs in docs/building.md; and the old README's §4.5 frame rules (every token gets a reply, acc not jid; src-tauri lib.rs and tests/embed.rs, protocol api.ts, backend.ts, frames.ts, the mock transport, worker/test/host.mjs) at libtacky's docs/using.md "Requests, replies, events". The libtacky submodule's own "From this clone" references are its own and stay. No behaviour changes; make check STRICT=1, make test-ui and make test-shell pass. 2026-10-27 08:27:00 +02:00
.gitignore make bundle-appimage builds the AppImage in the Rocky Linux 9 image: make appimage there with build trees of its own (build/backend-appimage for libtacky.a and the webrtc media library, src-tauri/target-appimage for the shell), so every native library in the bundle is compiled on EL9 and none is taken from the Debian build, sharing only the prebuilt libwebrtc and Chromium's clang. make docker-build runs it after the web image's half, which no longer builds the AppImage itself. docker/appimage.sh asks pkg-config and the file system where the image keeps GTK, GStreamer, its plugin scanner and the WebKit helpers instead of assuming Debian's layout, shortens the rewritten helper path to fit EL's shorter compiled-in one, drops the copies of EL9's GLib 2.68 that linuxdeploy's gtk plugin takes beside the image's 2.78, and refuses a bundle with an ELF that asks for a GLIBC_ or GLIBCXX_ version above the image's floors. The result, dist/another-im-tauri-0.5.1-x86_64.AppImage, needs at most GLIBC_2.35 (one symbol, _dl_find_object from EL9's own libgcc_eh, which EL9's glibc 2.34 carries as a backport; everything else stops at 2.34), GLIBCXX_3.4.29 and CXXABI_1.3.9, and it starts, renders the welcome screen and talks to libtacky under Xvfb on Ubuntu 22.04 and AlmaLinux 9. 2026-10-16 12:31:38 +03:00
.gitmodules The build follows libtacky v1.0.0-alpha7's layout, built and tested against the release candidate d0d79d4c (a standalone clone, ANOTHER_IM_TACKY), with the submodule pin left at v1.0.0-alpha4 until the tag exists: native/ is gone, so tacky-checkout no longer fetches libomemo-c (OMEMO is the Rust tacky-omemo and the backend needs none of its submodules here), BACKEND_VARS and the Flatpak manifest's make line name TACKY_MEDIA_BUILD and TACKY_MEDIA_DL instead of the OMEMO, libomemo-c and media trees, DEV_WATCH watches tacky/, ext/, tacky-core and tacky-omemo, and tools/flatpak-sources.py vendors the crates of the three Cargo.lock files make lib builds from, there being no workspace lockfile any more. The webrtc media backend is tacky-media/webrtc's libtackymedia_webrtc, a C library with no Tcl in it: webrtc.mk builds it from there without a Tcl prefix and make webrtc no longer waits for libtacky, the Android and Windows goals build it through tacky-media's own webrtc-android and win-webrtc (platforms/webrtc.mk is gone) and macOS through libtacky's webrtc-macos, and the file is libtackymedia_webrtc.{so,dll,dylib} everywhere the shell and the packaging name it (app.rs's WEBRTC_LIB, the AppImage, the Flatpak, the apk's jniLib and MainActivity's loadLibrary, the Windows installer and its smoke run). The browser worker links the new wasm archives (libtacky_omemo.a and libtacky_crypto.a in place of libomemo-c.a and libcrypto.a), calls Tackycore_Init, Tackyomemo_Init and Tackycrypto_Init beside Sqlite3_Init as embed/extensions.h lists them (Tackykeyring, Tackyxml and Tclcrypto are gone), dispatches to ::tacky::core::wire::dispatch, stops with ::tacky::backend destroy and releases acks with ::tacky::xmpp::session::durable_all; its boot and omemo suites use the renamed packages (tacky::core::storage's tacky_store, the typed tacky::core::keyring 0.2, tacky::omemo's ratchet commands, tacky::crypto, tacky::http) and bench-store's seed the renamed wire and store, though its OMEMO rows still use the removed high-level ratchet API. The connection suite is not ported: its fake peer was tacky-xmpp's FakePeer, which libtacky deleted with the crate, and the Tcl peer that replaced it needs tdom, which this image lacks. Checked in the image: make bundle-appimage (dist/another-im-tauri-0.3.6-x86_64.AppImage, 138,668,536 bytes, carrying libtackymedia_webrtc.so), make check clean, test-ui 130 files 1,644 passed, test-shell 17 binaries 93 passed, test-embed 74 and 6 passed against the built archive, the worker's spike 8, boot 35, omemo 3, host 18, store 64 and page 40 checks passed with test-connect failing on the missing crate, and make (dist/web) built. 2026-10-07 22:31:18 +03:00
audit.toml make audit passes, and leaves make check for a new make release-check (the user, 2026-10-27: everyday coding needs no network and is not blocked by a new advisory). src-tauri/Cargo.lock takes ctutils 0.4.4 (RUSTSEC-2026-0385), time 0.3.47 (-0009), tokio 1.53.3 (-0386, unsound) and plist 1.10.0, which brings quick-xml 0.41.0 (-0194, -0195), each a cargo update --precise in the image (time and plist need Rust 1.88, ctutils 1.87; every lane builds with 1.90, the Flatpak with the 25.08 SDK's rust-stable), and flatpak/cargo-sources.json is written again from it. crypto-bigint 0.5.5's RUSTSEC-2026-0387 goes into audit.toml: it comes in through p256 0.13 and elliptic-curve 0.13, and web-push-native 0.5, the latest, pins p256 ^0.13. p256 0.13 takes from it only the scalar's U256 add_mod, sub_mod, sbb, ct_lt and conditional_select, its multiplications being its own code. 0.5.5's sbb is the older WideWord form, before the branch #1029 brought into the 0.7 line, and the Montgomery multiplication, division, UintRef and BoxedMontyForm::invert fixed in 0.7.6 are never reached. The entry says this has not been BINSEC-verified and names p256 0.14 as the follow-up. make check is now tsc and i18n-check alone. make release-check runs check-pins and the audit, online, and docs/building.md's target table and README's Build section say it comes before every release. In the container: make audit clean (warnings only: the unmaintained gtk-rs/unic/zvariant set, glib's unsound advisory and a yanked yoke-derive, as before); make check STRICT=1 passed; test-shell passed; test-ui ran 4,048 of 4,049 under load, and the one failure, contact-info's this-device row, passed 49 of 49 alone (no UI code changed); cargo build --features desktop,fake-tacky --bin anotherim built. The libtacky pin stays where it is (libtacky fe96faeb is its own lock files and audit.toml). 2026-10-27 12:25:48 +02:00
CHANGELOG.md 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
LICENSE anotherim-web is MPL-2.0 (the user, 2026-09-29: "License is GPL-3.0 for libtacky and MPL 2.0 for anotherim-web and anotherim-swift"): LICENSE is the Mozilla Public License 2.0 text instead of the GPL-3.0's, ui/package.json and its lockfile's root entry and src-tauri/Cargo.toml say MPL-2.0, and the README gains a licence section that says so and that a build linking the GPL-3.0 libtacky (the worker, the Tauri shells) is conveyed under the GPL-3.0 as a whole, which MPL-2.0 permits 2026-09-29 22:56:13 +03:00
Makefile The WebKit smoke runs its screens in as many WebKit processes as the machine has threads and waits for the page instead of the clock (the user, 2026-10-27: "Why the gate is taking too long?"): a dispatcher hands the screens out longest first to SMOKE_JOBS workers, each with its own broadway display, file server and XDG directories, and prints every screen's lines in the list's order; the old sleeps (1.5s, 600ms an action, 50ms a check) became a virtual clock, every page timer stamped with the moment it would have fired and waited for only until that moment comes, plus fetches, finite animations, fonts and two frames after an action, never longer than the old schedule; checks are read until they hold for up to 3s; the storage is emptied before every screen and the first-run delivery sheet taken as seen, which had stood in front of "list header" whenever it ran first; docker/run.sh passes SMOKE_* (SMOKE_ONLY never reached the container), lifts the 2048-task cap and gives /dev/shm 4 GB, without which a dozen windows died of thread exhaustion and SIGBUS. 7,247 checks, ~50 minutes before, about one now. 2026-10-27 22:18:36 +02:00
README.md 0.7.11, on libtacky v1.1.11 (47df7fd7) (the user, 2026-10-27: "release the .11 versions with fixed locks - and upload them to 0.7 lane"): on Android the gate no longer puts the fingerprint prompt over the silent reopen at the phone's unlock (be489200); on the Mac and on Windows only the system's sleep closes the messages and Touch ID or Windows Hello is asked at the wake, a screen or session lock only holds the prompt, with the Hello fixes (4f39d14e, e40c236d); Telegram secret chats started from here no longer end at the peer's first message (libtacky 1.1.11). Version 0.7.11 and versionCode 7011 in ui/package.json and its lock, tauri.conf.json, Cargo.toml and Cargo.lock, README, docs/macos.md; a metainfo release and a CHANGELOG entry. Gates on this tree: make check STRICT=1 clean; make test-ui 4,308 passed, 8 skipped; make test-shell green; cargo check of the library for x86_64-pc-windows-gnu (fake-tacky) clean; the Kotlin JVM suite 492 passed on be489200 (no Kotlin since); the lock's tests on the Mac (42 device_lock and presence_key tests, real sleep and wake notifications) by the lock's worker. 2026-10-28 00:31:26 +02:00
webrtc.mk The build follows libtacky v1.0.0-alpha7's layout, built and tested against the release candidate d0d79d4c (a standalone clone, ANOTHER_IM_TACKY), with the submodule pin left at v1.0.0-alpha4 until the tag exists: native/ is gone, so tacky-checkout no longer fetches libomemo-c (OMEMO is the Rust tacky-omemo and the backend needs none of its submodules here), BACKEND_VARS and the Flatpak manifest's make line name TACKY_MEDIA_BUILD and TACKY_MEDIA_DL instead of the OMEMO, libomemo-c and media trees, DEV_WATCH watches tacky/, ext/, tacky-core and tacky-omemo, and tools/flatpak-sources.py vendors the crates of the three Cargo.lock files make lib builds from, there being no workspace lockfile any more. The webrtc media backend is tacky-media/webrtc's libtackymedia_webrtc, a C library with no Tcl in it: webrtc.mk builds it from there without a Tcl prefix and make webrtc no longer waits for libtacky, the Android and Windows goals build it through tacky-media's own webrtc-android and win-webrtc (platforms/webrtc.mk is gone) and macOS through libtacky's webrtc-macos, and the file is libtackymedia_webrtc.{so,dll,dylib} everywhere the shell and the packaging name it (app.rs's WEBRTC_LIB, the AppImage, the Flatpak, the apk's jniLib and MainActivity's loadLibrary, the Windows installer and its smoke run). The browser worker links the new wasm archives (libtacky_omemo.a and libtacky_crypto.a in place of libomemo-c.a and libcrypto.a), calls Tackycore_Init, Tackyomemo_Init and Tackycrypto_Init beside Sqlite3_Init as embed/extensions.h lists them (Tackykeyring, Tackyxml and Tclcrypto are gone), dispatches to ::tacky::core::wire::dispatch, stops with ::tacky::backend destroy and releases acks with ::tacky::xmpp::session::durable_all; its boot and omemo suites use the renamed packages (tacky::core::storage's tacky_store, the typed tacky::core::keyring 0.2, tacky::omemo's ratchet commands, tacky::crypto, tacky::http) and bench-store's seed the renamed wire and store, though its OMEMO rows still use the removed high-level ratchet API. The connection suite is not ported: its fake peer was tacky-xmpp's FakePeer, which libtacky deleted with the crate, and the Tcl peer that replaced it needs tdom, which this image lacks. Checked in the image: make bundle-appimage (dist/another-im-tauri-0.3.6-x86_64.AppImage, 138,668,536 bytes, carrying libtackymedia_webrtc.so), make check clean, test-ui 130 files 1,644 passed, test-shell 17 binaries 93 passed, test-embed 74 and 6 passed against the built archive, the worker's spike 8, boot 35, omemo 3, host 18, store 64 and page 40 checks passed with test-connect failing on the missing crate, and make (dist/web) built. 2026-10-07 22:31:18 +03:00

anotherim-js

Another IM is an XMPP messenger. This repository holds its client: one UI in TypeScript with lit, in a browser tab, a desktop app for Linux, Windows and macOS (a Tauri 2 shell), and an Android app (the same shell, plus Kotlin for push, calls and files).

Version 0.7.11. Breaking changes are still possible. Licence MPL-2.0.

The desktop window in the Night theme over a wallpaper: the chat list with pictures, pins, unread and muted rooms, Telegram contacts; a 1:1 chat with OMEMO, a photo, a reply, a sticker, reactions

A group chat on a phone in the Day theme, with two @-mentions The chat list on a phone in the Night theme: pinned chats, rooms with unread mentions, a muted room, Telegram contacts

A chat on the desktop; a group chat with @-mentions and the chat list on a phone. The people are invented: make screenshots draws them from the mock backend.

Features

  • Several accounts; sign in by password, OAuth or an SSO broker; sign up with CAPTCHA or proof-of-work
  • 1:1 and group chats with server history, replies, edits, reactions, threads, pins and search
  • Delivery ticks and read markers; retracted messages kept, with edit history
  • Albums with captions, silent and scheduled messages, polls, places, stickers
  • @-mentions, rooms on "mentions only", roles and moderation
  • OMEMO in chats and private rooms, keys verified by QR code
  • Telegram and other networks through gateways, Telegram secret chats in the apps
  • Local store encrypted by default with the system keyring
  • HTTP upload and direct device-to-device transfer, voice and round video messages
  • 1:1 audio and video calls
  • Push while closed: Web Push, UnifiedPush, FCM
  • Night and Day themes, five languages, backup and restore

The whole list is in docs/features.md, with what has not been tried on a real device yet. Tests run against a mock backend, not real servers.

Download

Builds of each release are on the releases page: the Android apk (UnifiedPush, or FCM in the -gms one), the Linux AppImage and Flatpak, the Windows installer and portable zip, and the browser client as a tarball to serve yourself (docs/building.md).

platform minimum
Chromium browsers 97 ('wasm-unsafe-eval' in the CSP)
Firefox 114 (module workers)
Safari, iOS 16
Android app Android 11, arm64; WebView 80
Linux AppImage glibc 2.35, or EL9's 2.34; x86_64
Linux Flatpak GNOME 50 runtime, x86_64
Windows 10 or 11, x86_64, with WebView2
macOS 11, Apple silicon

An engine too old for the bundle shows "This browser is too old" (or, on Android, "Update Android System WebView") instead of a blank page.

Build

Everything builds in this repository's container images. The host needs git and podman (or docker); make <goal> runs the goal in the container. A Mac builds on the Mac (docs/macos.md).

git clone --recurse-submodules https://dev.another.im/another-im/anotherim-js.git
cd anotherim-js
make docker-build             # backend, dist/web, web tarball, AppImage
make test-ui check test-shell # the tests that need no backend
make dev                      # the UI on http://localhost:5173 (DEV_BACKEND=mock: no backend)

make release-check runs make check-pins and make audit, the RustSec audit of src-tauri/Cargo.lock, before a release; make check stays offline (docs/building.md).

build target
Browser make web-tar
Linux make bundle-appimage, make bundle-flatpak
Windows make bundle-windows
Android make bundle-android, make bundle-android-gms ANOTHER_IM_GOOGLE_SERVICES=<file>
macOS make bundle-macos, on a Mac

make help lists every target. Outputs, signing, build knobs, command-line options and serving the browser client are in docs/building.md.

How it fits together

The UI does not speak XMPP itself. Protocol, storage, encryption, calls and file transfer all come from libtacky, through its JSON wire API.

                ui/                 TypeScript + lit: views, state, the wire API
                 │                  one Transport interface, three implementations
     ┌───────────┼────────────┐
   mock        worker        tauri
  in-page    libtacky as     libtacky.a in the Tauri shell
  (dev)     wasm (browser)   (desktop, Android)
component language what it is code tests coverage
ui/ TypeScript the client: views (41,838), state (24,224), protocol and the mock backend (9,667), the rest (1,756) 77,485 82,057 99.0%
JS two boot scripts that catch an old browser 73 -- not measured
src-tauri/ Rust the shell: libtacky binding, files, notices, push, tray, windows 8,768 5,807 95.4% (all of src-tauri/src on Linux)
src-tauri/gen/android/ Kotlin push, notifications, calls, files, share target 5,437 7,204 96.5%
worker/ JS the worker, its OPFS store and file system 880 1,997 99.9%
C the backend host compiled to wasm 439 -- not measured
Tcl a package index for stubs 4 -- not measured
total TypeScript 77,485 · Rust 8,768 · Kotlin 5,437 · JS 953 · C 439 · Tcl 4 93,086 97,065
everything else make, sh, Python, JS tools/, docker/, flatpak/, the Makefiles; not in the total 9,092 -- --

Measured on 2026-10-27 at 7a0cf4ed, v0.7.10 (libtacky 1b5b33de, v1.1.10).

  • code: non-blank, non-comment lines of the files git tracks, by the rules of libtacky's tools/stats.py. The generated wire API (ui/src/protocol/generated/api.ts, 15,991 lines), JSON, CSS, HTML and the language catalogues are not counted.
  • tests: ui/test/, src-tauri/tests/, Rust #[cfg(test)] modules, Kotlin src/test/ and src/testGms/, worker/test/.
  • coverage: line coverage. make coverage-ui runs the UI tests under V8 over every ui/src file but the generated API: 58,663 of 59,277 lines, 90.8% of branches. make coverage-shell-all runs all of src-tauri/src on Linux under LLVM, with libtacky faked (feature fake-tacky): 95.4%. make coverage-android runs the Kotlin unit tests under JaCoCo with Robolectric: 3,380 of 3,501 lines (96.5%). make coverage-worker runs the worker's node suites: 873 of 874 lines. Measured 2026-10-27.

Tests

suite command files cases last run
UI (vitest, happy-dom) make test-ui 388 4,300 2026-10-27: 4,292 passed, 8 skipped
Types and catalogues make check -- -- 2026-10-27: passed, 2,122 strings in all five languages
Shell, plain-std modules make test-shell 34 274 2026-10-27: all passed
Shell, whole crate with libtacky.a make test-embed 41 263 not run for this count
Android JVM unit tests gradle in the android image (make coverage-android) 48 492 2026-10-27: all passed
wasm worker under node make test-worker 5 -- 2026-10-27: all passed
WebKitGTK layout smoke make webkit-smoke 1 7,315 checks 2026-10-27: all passed
Chromium smoke of dist/web make web-smoke 1 1 not run for this count

Docs

Licence

anotherim-js is MPL-2.0 (LICENSE). libtacky is GPL-3.0, so a build as a whole is distributed under the GPL-3.0. Bundled third-party parts:

  • Fira Sans Condensed, SIL Open Font License 1.1 (ui/public/fonts/OFL.txt)
  • Lucide icons, ISC, some from Feather, MIT (ui/public/licenses/lucide.txt)
  • FFmpeg decoders for H.264, HEVC and AAC in the AppImage, LGPL-2.1+ (patent-encumbered in some countries)

The two sounds are generated by tools/sounds/make-sounds.py.