Transfer anything across your local network — instantly, privately, at any size.
Your team's own private transfer cloud. No accounts, no third-party cloud, no file-size limits.
#file-transfer #self-hosted #local-network #intranet #zero-config #privacy-first
MeghXL is a free, open-source, self-hosted file transfer tool for your local network — an AirDrop and WeTransfer alternative that works on Windows, macOS, Linux, Android and iOS without installing anything on the receiving device.
Run one command on a PC and MeghXL turns it into a private file-transfer hub for your whole network. Drop a file in the dashboard and it instantly appears on every connected device with a download button and a QR code. The receiving side needs nothing but a browser — no app, no account, no sign-in.
It's built for offices, teams, and large networks: your files never leave your network unless you explicitly choose to share them, and there are no per-file size caps or cloud middlemen.
A matily.org product. Free and open source under the Apache 2.0 license.
| MeghXL | LocalSend | PairDrop / Snapdrop | WeTransfer | |
|---|---|---|---|---|
| Install on the receiving device | Nothing — any browser | App on every device | Browser on both ends | Browser |
| Works with no internet | Yes | Yes | Yes, if self-hosted | No |
| Files leave your network | Never | Never | Never | Yes — uploaded to their cloud |
| Size limit | Your disk | Your disk | Varies | Capped by plan |
| Files stay available after transfer | Yes — a shared board | No, one-shot | No, one-shot | Until the link expires |
| Admin controls for an office | Yes — host console | No | No | Paid plans |
| Accounts required | None | None | None | For most features |
MeghXL takes the hub-and-spoke approach rather than peer-to-peer: one computer runs the server and everything else just opens a browser. That's the trade-off — one machine has to be on, and in exchange nobody else installs anything.
The shared dashboard (left) and the host console (right).
- Drag and drop — or click, or paste from the clipboard — to share a file.
- Live dashboard — a public file dropped on one device appears on every other open dashboard within a second, over WebSocket.
- Instant QR and link for every file, plus a "scan to join" QR for the dashboard itself — shown in the terminal and in the UI.
- Public or private, per file — public files appear on the shared dashboard; private files are reachable only through their unguessable link or QR.
- One-time links (burn after download) — share a file that deletes itself the moment it is downloaded once.
- Auto-expiry — make any private link self-destruct after a set time.
- Shared clipboard — a text box whose notes sync live across all devices, for pasting a URL, a code, or a Wi-Fi password between machines.
- Any size — uploads stream straight to disk (no memory blowup) and downloads support HTTP Range, so they are resumable.
- Friendly name (mDNS) — reachable at
http://meghxl.local:3000; bookmark it once per device and it is one click forever. - LAN-only by design — MeghXL never exposes itself to the internet. For
remote access, put it behind your own VPN or authenticated reverse proxy and
set
PUBLIC_BASE_URL(so links/QRs point at that address). - Always-on mode — one command makes a "mother PC" serve on every boot.
- Host console — a private
/adminpage on the host PC to see connected devices, block or unblock them, broadcast announcements, and manage files. - Shared message board — post a note to everyone on the network, or send a private message to one device. Both appear live.
- In-app updates — the About page (and the desktop tray) can check GitHub for a new release and show its changelog. The desktop app downloads and installs signed updates itself. It only ever checks when you press the button.
- Tiny and readable — a vanilla front-end with no build step, seven runtime
dependencies, and a single
node server.js.
Only the computer acting as the hub needs this — every other device just opens a browser. No Node.js required.
| Platform | File | Notes |
|---|---|---|
| macOS (Apple Silicon) | Download .dmg | M1/M2/M3/M4 Macs |
| macOS (Intel) | Download .dmg | x64 build |
| Windows 10/11 (x64) | Download installer | NSIS .exe or .msi |
| Linux (x64) | Download .AppImage / .deb | Most distributions |
Every installer is fully self-contained — the server is compiled in, so there is no runtime to install. Open it and the dashboard appears; a tray icon keeps it running. The app checks for updates when you ask it to, and installs signed releases in place.
macOS note: builds are not notarized with Apple; on first launch, right-click the app and choose Open. Windows shows SmartScreen — More info → Run anyway. Building from source avoids both.
Three steps. Only one computer installs anything.
This is the machine everyone shares through — an office PC, a spare laptop, a Mac in the corner. Install MeghXL on it from Download above and open it. That's the whole setup.
You'll see the dashboard, and the app shows the address other devices should use:
meghxl.local:3000
Phones, laptops, tablets — anything with a browser, on the same Wi-Fi:
- Scan the QR code — click Add a device in the sidebar and point a phone camera at it. Fastest way, and no typing.
- Or type
meghxl.local:3000into the browser.
If a device can't open
meghxl.local— some Android browsers don't resolve.localnames — use the numeric address instead. It's in the host's tray menu under Copy network link, and on the host console under Settings.
Bookmark it once per device and it's one tap forever.
On any device, go to Send, drag a file in, choose who gets it, and press Send:
| Send to | What happens |
|---|---|
| Everyone | Appears on every device's Dashboard, live |
| Private link | Only someone with the link can open it — it's in no list |
| A specific device | Goes straight to that one device's Private tab |
Before sending you can set an expiry, or tick one-time so the file deletes itself the moment it's downloaded once.
That's it. Files download to each device normally; nothing else to install.
Two things worth doing on the hub:
- Turn on Start at login in the tray menu, so the hub is always ready.
- Open the Host console (visible only on the hub) to see connected devices, post an announcement, or clear old files.
Prefer a terminal, or running it on a headless box or NAS? Requires Node.js 18+.
git clone https://github.com/riponcm/MeghXL.git
cd MeghXL
npm install
npm startThe terminal prints your network URL and a scannable QR code:
+---------------------------------------------+
| MeghXL is running |
| |
| On this computer: http://localhost:3000 |
| On your network: http://192.168.x.x:3000 |
| Friendly name: http://meghxl.local:3000|
| |
| Scan to open on your phone: [QR code] |
+---------------------------------------------+
On any other device on the same network, scan the QR (or open
http://<your-ip>:3000, or http://meghxl.local:3000) and the dashboard loads.
Drop a file on one device, grab it on another.
On macOS the first run may show a firewall prompt — click Allow so other devices can reach the port.
- The server binds to
0.0.0.0so every device on your LAN can reach it, and auto-detects your IPv4 to build shareable links. - Uploads stream to
uploads/under a random filename; the original name, size, type, and a random token are recorded inmetadata.json. - The token is the access control:
GET /d/<token>serves the file. Public files are also listed on the dashboard; private files never appear in any list. - A WebSocket fans out
file-added/file-removed/note-addedevents so every dashboard stays live.
All optional — set as environment variables (for example, PORT=8080 npm start):
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
Port to listen on |
MAX_UPLOAD_MB |
(unlimited) | Cap upload size in MB; unset or 0 = no limit |
UPLOAD_DIR |
./uploads |
Where files are stored |
DATA_FILE |
./metadata.json |
Metadata store path |
PUBLIC_BASE_URL |
(unset) | Override the base URL for all links and QRs |
MDNS_NAME |
meghxl |
The <name>.local mDNS hostname to advertise |
MDNS |
(on) | Set to off to disable mDNS advertising |
ADMIN_IP |
(unset) | Extra PC(s), by LAN IP, that get the host console |
ADMIN_KEY |
(unset) | Optional key for remote admin (e.g. behind a VPN/proxy) |
MeghXL has a private control panel at /admin:
- On the computer running the server, it opens automatically — no key, no
login. Every browser on that machine is admin (works via
localhost, the LAN IP, ormeghxl.local). - Every other device on the network just sees the normal dashboard — the console is never exposed to them.
- Need admin from a different PC? Designate it by LAN IP with
ADMIN_IP=..., or useADMIN_KEY.
From the console you can manage devices (block/unblock, send a file), broadcast announcements, manage every file, and adjust settings (default expiry). Device names, blocks, and announcements persist across restarts.
MeghXL is LAN-only by design and never exposes itself to the internet — there is no "go public" button. Keeping internet exposure out of the app is a deliberate security choice for an internal tool.
If you genuinely need access from outside your network, do it the safe way: put MeghXL behind infrastructure you control and authenticate — a VPN (WireGuard / Tailscale) or an authenticated reverse proxy — then point links and QR codes at that address:
PUBLIC_BASE_URL=https://meghxl.your-company.com npm startWhatever you expose it through, add authentication at that layer. On the LAN itself, treat the network as trusted and use private + expiry + one-time links for anything sensitive.
Make one PC the always-on hub so the others just click their bookmark:
npm run autostart:install # macOS: starts now, and on every login
npm run autostart:uninstall # remove it(macOS/launchd today; the script is a small template you can mirror with
systemd --user on Linux or the Startup folder on Windows.)
MeghXL also ships as a real native app — a Tauri shell around the same server, so the machine hosting it needs no Node.js installation and no terminal. Double-click, and the dashboard opens in its own window.
cd desktop
npm install
npm run build # → desktop/src-tauri/target/release/bundle/You get MeghXL.app and a .dmg on macOS, and an .msi / NSIS installer on
Windows. It weighs about 25 MB — the server is compiled into a single
executable with bun build --compile and bundled as a Tauri sidecar, so there
is no runtime to install.
What the app adds over npm start:
- Tray icon — open the dashboard or host console, copy the network link, or toggle Start at login. Closing the window parks MeghXL in the tray; the server keeps serving your other devices.
- Cross-platform autostart, replacing the macOS-only
autostart:installscript. - Attaches instead of colliding — if a MeghXL server is already running on port 3000 (from the terminal or the autostart agent), the app uses it rather than starting a second one, and never stops a server it did not start.
- Files stored outside the bundle — transfers and metadata live in your user data directory, so they survive app updates.
Building it needs Rust and Bun (plus Xcode Command Line Tools on macOS). Tauri cannot cross-compile between macOS and Windows — build each on its own machine, or use a CI matrix.
The released binaries are currently unsigned, so macOS shows an "unidentified developer" warning on first launch (right-click → Open), and Windows shows a SmartScreen prompt. Building from source avoids both.
MeghXL is just getting started. On the way:
- Native desktop app (macOS / Windows) — Tauri shell with a tray icon, no Node.js needed
- Signed and notarized releases, so the installers open without a warning
- Android and iOS apps, with share-sheet sending
- End-to-end encryption for private transfers
- Share-sheet sending straight from your phone
- Transfer history with resume
- Optional auth layer for
PUBLIC_BASE_URLdeployments (password / SSO) - Group devices by PC — merge a machine's browsers into one device (by LAN IP, named by OS) instead of one entry per browser; native apps will enable true per-device identity
- Multi-language UI — English, বাংলা (Bengali), हिन्दी (Hindi), and more
- Themes — light, dark, and custom accent colors
Want a say in what ships next? Watch → Custom → Releases and open an issue with your request.
If MeghXL saves you time, a star genuinely helps it reach more people — and Watch → Releases is the easiest way to hear the moment the native mobile and desktop apps drop.
A full video tutorial is coming soon. Sharing MeghXL with your team is the best thanks.
MeghXL makes one outbound request in its entire lifetime, and only when you
press Check for updates in the About page or the desktop tray: a single GET
to the GitHub releases API to compare version numbers. It sends no identifiers,
no filenames and no usage data, and the answer is cached for an hour. Nothing
runs on a timer or at launch.
Desktop updates are signature-verified — the app installs only a package signed with the project's key, checked against the public key compiled into the bundle, so a compromised download cannot push you malicious code.
Don't want it at all? Delete src/routes/update.js and its app.use line in
server.js. Nothing else depends on it.
Full policy: see SECURITY.md for the complete threat model, how to report a vulnerability, and a 10-minute checklist to audit the code yourself (no telemetry, no install scripts, no dynamic code execution).
MeghXL assumes your local network is trusted. On the LAN, anyone who can reach the URL can see and download public files, post clipboard notes, and upload — that is the point of a same-network sharing tool.
What it protects against:
- Path traversal — client filenames never touch the filesystem; downloads are served only by random token to a server-generated stored name, with a containment check.
- Guessing private links — tokens are 128-bit, URL-safe random strings.
- Memory exhaustion — uploads stream to disk; request bodies are size-capped.
For sensitive files, use a private share with an expiry and/or a one-time download.
npm run dev # auto-restart on changes (node --watch)
npm test # run the test suite (node --test)Project layout:
server.js entry — wires Express + WebSocket on one port
src/ config, networking, store, uploads, qr, ws hub, routes
public/ the no-build dashboard (HTML/CSS/JS)
desktop/ native app — Tauri shell + the server as a sidecar binary
assets/ brand assets (logo, hero, previews)
uploads/ runtime file storage (git-ignored)
Run MeghXL on one of them (npm start, or open the desktop app). It prints a URL
and a QR code. On the other computer, open that URL in any browser and drag your
file onto the page — it appears on the first machine immediately.
Yes — this is one. AirDrop only works between Apple devices. MeghXL works between anything with a browser, so a Windows PC, a Mac, an Android phone and an iPhone can all share the same board at once.
Yes. MeghXL only needs the devices to be on the same Wi-Fi or LAN. Nothing is uploaded to any cloud, and no account or sign-in exists.
There is no size limit beyond your disk. Uploads stream straight to disk instead of being buffered in memory, and downloads support HTTP Range, so they resume rather than restarting.
Yes. Send it as a private link, or straight to a single device from the Send screen. Private files never appear on anyone else's dashboard. Add an expiry or make it a one-time link that deletes itself after a single download.
MeghXL is designed for a network you already trust. Anyone who can reach the URL can see public files, so treat it like a shared drive. The host console — device blocking, announcements, file management — is restricted to the machine running the server, and verified at the socket rather than from a spoofable header. For anything sensitive, use a private link with an expiry. See SECURITY.md.
No. Phones just scan the QR code and use their browser. Only the computer acting as the hub runs MeghXL.
Not directly, and that is deliberate — MeghXL never exposes itself to the internet.
Put it behind your own VPN or an authenticated reverse proxy and set
PUBLIC_BASE_URL. See Remote access.
Issues and pull requests are welcome. The codebase is intentionally small and
dependency-light — read server.js and src/ and you will have the whole picture
in a few minutes.
Start with CONTRIBUTING.md — it covers setup and, more importantly, the design constraints that are load-bearing (LAN-only, no build step, no telemetry, the receiver installs nothing). Release history lives in CHANGELOG.md.
MeghXL is another open-source project from Matily — built with care on Node.js and Express, with a vanilla, build-free front-end.
Development memory was kept with projectmem (projectmem.dev) — local-first memory for AI coding agents, which recorded the decisions, gotchas and failed approaches behind this codebase so they were not repeated.
If MeghXL is useful to you, please star and share the repo. Contributions, issues, and ideas are always welcome.
Apache License 2.0 — free to use, fork, modify and ship, including commercially. It adds an explicit patent grant and asks that you keep the notices in NOTICE and state any changes you make.

