Messaging for the people around you. No internet needed.
Start a network on an Android phone, a laptop or a Raspberry Pi. People nearby scan a code and
start talking: no accounts, no cloud, nothing to install.
loamnet.com · Start a network · Operator's guide · Docs
LOAM is local communication for places where the internet is missing, overloaded or not the right tool: an outage, an emergency, a festival, a campsite, a community space. One device becomes the host and runs the network. Everyone nearby scans its code, LOAM opens in their browser, and they can post in channels, reply in threads, send direct messages, share pictures and react. Everything stays on the host and on the phones of the people using it, plus any other LOAM network the host links to, which receives the public channels.
Its priorities, in order: simplicity (scan and go), privacy (no accounts, nothing collected) and resilience (low bandwidth, connections that come and go).
The name is a backronym: Local Off-grid Ad-hoc Messaging. (Yes, it's also a type of soil. We picked the word first and worked out the letters afterwards.)
- Download
loam-host.apkfrom the latest release and open it to install. Your phone may ask you to allow installs from your browser. (To check the file on a computer first:sha256sum -c loam-host.apk.sha256with the checksum from the same release, orgh attestation verify loam-host.apk --repo MagicZebraLtd/loam.) - Answer four questions: your language, the kind of network (see below), its name, and how people connect: Hotspot (the phone makes its own Wi-Fi, no router needed) or Wi-Fi (everyone on the Wi-Fi the phone is already on). The same app runs on Android tablets and on Android laptops such as the Googlebook, in any window size or orientation. A laptop that cannot start its own hotspot hosts in Wi-Fi mode, on the network it is already on (wired or wireless).
- Show the code. The share screen shows what people scan. Display mode puts it full screen, keeps the screen on and pins LOAM in front, for a phone left where people can see it.
The host phone is the network's admin automatically. Needs 64-bit Android 7 or newer; hosting a hotspot needs Android 8 or newer.
The desktop app is the double-click way: download LOAM for your system from loamnet.com/desktop, open it, answer a few questions, and it shows the code to scan. Closing its window keeps the network running; Quit stops it. It ships with LOAM 0.7.0. The Mac app is signed and notarized by Apple. The Windows installer isn't signed yet, so Windows asks you to confirm it once. The Windows, Linux and Intel Mac builds have so far only been checked automatically, not run on real machines, and the Windows and Linux builds are for 64-bit Intel or AMD computers only. docs/24 has the details.
npx loamnetIt opens LOAM's terminal screen, with the QR code to scan (see below). Needs Node.js 22.14 or newer.
npx loamnet --port 8080 # another port (by default 3000, or the next free one)
npx loamnet --data-dir ~/loam # where to keep the data (default ~/.loam)
npx loamnet --encrypt # encrypt the database (asks for a passphrase); pictures and
# files are stored beside it, unencrypted
npx loamnet --kiosk # start locked, showing only the join QR
npx loamnet --plain # print the QR and addresses instead (also what a service gets)
npm install -g loamnet && loam # install it for goodIn a terminal, loamnet takes over the window (your scrollback comes back when it stops) and keeps the
join code on screen. Everything else is a number key away, and ? lists the keys:
| Key | Screen | What it's for |
|---|---|---|
| 1 | Join | The QR code and the address. o opens LOAM in your browser as the network's admin (p then shows a QR that makes a phone admin), a picks which network address to advertise, h hides the code. |
| 2 | Activity | Requests and problems as they happen. e shows only problems, space pauses. |
| 3 | People | Who has joined and who is online. m makes someone an admin. |
| 4 | Settings | The network's name, security profile, who can join, encryption and how long messages last, changed live; a code to link another network; Emergency Reset; and the port and kiosk mode for next time. |
| 5 | Debug | Versions, how the node is set up, recent problems, detailed logging, and a diagnostics file for a bug report. |
Messages, approvals and moderation stay in the web app. Nobody becomes admin just by opening a new network first: admin comes from this screen.
Kiosk mode (k, or start with --kiosk) locks the terminal to the join code, the network's name
and the number of connected devices until a password is entered, so a computer can be left on a desk
for people to join from. It locks the screen, not the computer.
Run as a service, or with --plain, loamnet prints the address and the QR code instead.
More in the loamnet README.
Any phone, tablet or computer joins from its browser, iPhones included: connect to the same Wi-Fi or hotspot, scan the code, and LOAM opens. There is nothing to install and no account to make. The code also carries the network's encryption key, so messages to and from the host are encrypted from the start.
- Channels, threads and direct messages. Public channels, private ones by invitation, threaded replies, one-to-one messages, reactions, pictures and files, and search.
- No sign-up. Everyone gets a generated name and picture, or picks their own if the network allows it. No email, no phone number.
- Moderation. Approve newcomers, appoint moderators and greeters, handle reports, ban, time out or shadow-ban. Anyone can block someone they'd rather not hear from.
- Invite codes. On a network that approves newcomers, the host phone's code lets people straight in. It changes every 10 minutes, so an old photo of it stops working.
- Link networks. Two LOAM networks can share their public channels both ways. The existing network shows a single-use link code; the other phone scans it during setup. Direct messages and private channels never leave either network. (Mesh mail, experimental and off by default, can travel through linked networks, sealed so that only its recipient's network can open it.)
- Emergency reset. Press and hold to erase the whole network at once, on the host and on every phone connected to it.
- Fifteen languages, left to right and right to left: English, Español, Français, العربية, فارسی, Português, Українська, Русский, Türkçe, မြန်မာ, اردو, دری, پښتو, Kiswahili and বাংলা. The host picks one for the whole network. The 14 besides English are machine translations still waiting for a native speaker's review (docs/13).
- Copes with a bad signal. Phones keep what they've already seen and reconnect on their own.
- An assistant, if you want one. It answers in direct messages, from a small AI model on the host phone, from Ollama or another model server on a computer nearby, or from an online service with an OpenAI-style API, such as OpenRouter or OpenAI. The first two need no internet. An online service gets the messages people write to the assistant, and both the admin page and the assistant's chat say so. Off unless you turn it on (docs/06).
The setup in the Android app and in the desktop app offers three. Everything can be changed later in the admin area.
| Who can join | Names | Messages | Stored on the host | |
|---|---|---|---|---|
| Community | anyone nearby | people choose a name and photo | kept until erased | encrypted, survives a restart |
| Private and short-lived | each person approved first | random names and pictures | disappear after an hour (by default) | encrypted under a key that exists only while LOAM runs |
| Choose every setting myself | your choice | your choice | your choice | encrypted unless you turn it off |
A Private network also only accepts encrypted connections and doesn't show who is online. On a computer, the same settings live in the admin area as security profiles (docs/09).
- Nothing to collect. No accounts, no analytics, no advertising, no crash reporting. Messages stay on the host and on the phones that received them, unless the host links another network or turns on an online assistant (How it works). That also means LOAM never tells us when something goes wrong, so if you find a problem, or would like to ask for a feature, please open an issue or email Magic Zebra Ltd at opensource@magiczebra.co.uk.
- Encrypted connections. Joining by the code sets up an encrypted connection to the host (an X25519 handshake and XChaCha20-Poly1305), so someone listening on the Wi-Fi can't read the messages. The app itself still arrives over plain HTTP, so someone who can change traffic on the network while the page loads could give a phone a tampered copy that reads its messages (the host app's own window isn't exposed to that). By default, pictures and files are downloaded unencrypted, so someone on the same Wi-Fi could see them; a network that requires encryption (the Private one does) encrypts those too, and refuses anyone who didn't join by the code (docs/08). Why not HTTPS: a hotspot with no internet can't get a certificate, so LOAM serves plain HTTP and encrypts inside the app instead, using the noble libraries and the host key carried in the code. It has had no outside security audit yet.
- Encrypted storage. The host can keep its database encrypted with SQLCipher, under a key held in the device's keystore or keychain, a passphrase, or a key that lives only in memory. An encrypted setting never falls back to storing data unencrypted. Pictures and files are stored beside the database, not encrypted; an Emergency reset deletes them.
- Emergency reset. Erases every message, person, picture and file, and tells connected phones to
clear their copy. On an encrypted network in the Android or desktop app, and in
loamnetwith a key that lives only in memory, the key is replaced too, so what's left in the database files can't be read (docs/02).
Know the limits. The host can read every message: it's the server, as the operator of any chat
service can. A host device taken while it's running, with the key in memory, can give up what it holds.
LOAM is built for a local network: on an address reachable from the internet, anyone who finds an open
network can join it, so a host that must do that should require approval to join and require encryption
(docs/12). Encrypted storage on a physical Android phone (keying, rekeying
and the reset) hasn't yet been through the full device checklist
(docs/21); it is tested in code and CI. LOAM raises the bar;
it isn't a guarantee.
If your safety depends on it, get a professional review first. SECURITY.md has the full
threat model, and every network serves its own privacy policy at /privacy (also on
loamnet.com).
LOAM is for people 18 and over. That isn't because of anything in it: LOAM is a plain messaging tool with no content of its own, nothing to browse and no feed, so people only see what others on their network write. It's because of how it works. There are no accounts, names are anonymous, and each network is run by whoever starts it, with no company in the middle, so nobody can check ages or look out for children the way an app made for them has to. Rather than pretend otherwise, LOAM is for adults. Our child safety standards say how abuse is handled.
The host runs everything: the LOAM server (Node.js, Fastify), its database (SQLite) and the web app it hands to each phone that connects. Phones talk to it over the local network. Nothing goes to the internet unless the host turns on an online assistant, which the admin page warns about, or links another LOAM network, which then receives the public channels. Switch the host off and the network is gone.
flowchart LR
P1["📱 Phone"] -->|"Wi-Fi + scan the code"| Host
P2["📱 Phone"] -->|"Wi-Fi + scan the code"| Host
P3["💻 Laptop"] -->|"Wi-Fi + scan the code"| Host
subgraph Host["Host: Android phone, computer or Raspberry Pi"]
direction TB
S["LOAM server"] --- C["Web app"]
S --- DB[("Database, optionally encrypted")]
end
The Android app packs a whole host into one phone: it runs the same server on an embedded Node.js, raises a local-only hotspot, and shows the web app in its own screen. The browser app is a Preact PWA that keeps a local copy of what it has seen and reconnects by itself. Client and server share one set of Zod schemas, so the two can't drift apart.
Linked networks pull each other's public content (docs/11). An experimental opportunistic mesh, where a third person's phone carries a sealed message between two people who can't reach each other, is built on the server but not yet verified on real radios (docs/16).
You'll need Node.js 24.15.0 and pnpm 10 (corepack enable sets pnpm
up).
pnpm install
pnpm dev # server + web app together, and a join QR in the terminal
pnpm build # every package, the server and the web app (type-checks as it goes)
pnpm test # the whole test suiteIn development the web app runs on :3000 and proxies the API to the server on :3001. In production
they're one process: pnpm build && pnpm --filter @loam/server start, which is what the loamnet
package bundles.
The Android app needs Android Studio (its JDK, the Android
SDK and NDK r27 or newer) and adb on your PATH:
pnpm --filter app apk # → apps/app/loam-host.apk (a few minutes)
adb install -r apps/app/loam-host.apk # onto a phone with USB debugging on
pnpm --filter app typecheck # its own type-check (CI runs it too)Without a release key (pnpm --filter app keystore) the APK is signed with your machine's debug key,
and the build says so. A debug-signed APK can't update a release-signed install.
docs/04 covers the app in depth.
| Path | What it is |
|---|---|
apps/server |
The server: REST and WebSocket, SQLite (optionally SQLCipher), sync, mesh, assistant. |
apps/client |
The web app everyone uses (Preact, Vite). |
apps/app |
The Android host app (Expo, React Native, embedded Node.js). |
apps/desktop |
The desktop host app for Mac, Windows and Linux (Electron). |
apps/site |
loamnet.com. |
cli |
The loamnet npm package. |
packages/* |
The shared schemas, names, avatars, QR codes and crypto. |
ARCHITECTURE.md is the fastest way into the codebase for people; AI agents start at CLAUDE.md. CI checks
that every package version agrees, then builds, tests, type-checks the Android app and smoke-tests the
packed CLI on every push and pull request to master.
- Operator's guide: running a network, from setup to emergency.
- Android host app · Desktop app · The
loamnetpackage - Transport security · Security profiles
· Emergency reset ·
SECURITY.md - Linking networks · Opportunistic mesh
- Languages · The assistant
- Mission · Acceptable use · Roadmap
LOAM is free, with no ads and no in-app purchases. If it helped you, you can support its development on Ko-fi, or star the repo and tell people about it.
LOAM is licensed under the GNU Affero General Public License v3.0. Copyright © Magic Zebra Ltd. If you run a modified LOAM as a service, the AGPL asks you to offer its users the source.