magic-wormhole: file transfer that starts with two spoken words
get things from one computer to another, safely
At a glance
- What is it?
- A Python library and command-line tool that moves files between two machines over a short pronounceable code. The README is short, and the interesting engineering lives in two separate server repositories and the transit relay.
- Who is it for?
- magic-wormhole is at its best as the ninety-second answer to a problem that has stalled: getting a file to someone who is not on your network without opening a port or pasting a base64 blob into chat. The code exchange is genuinely short, tab completion removes the typing burden, and single-use codes mean a leaked code is not a standing credential.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A wormhole code as the entire handshake
The package provides a library and a command-line tool named `wormhole` that makes it possible to get arbitrary-sized files and directories, or short pieces of text, from one computer to another. The two endpoints are identified by identical wormhole codes: the sending machine generates and displays the code, which must then be typed into the receiving machine.
The design decisions that follow from that sentence are what separate this from other transfer tools. The codes are short and human-pronounceable, drawn from a phonetically-distinct wordlist, which means a code can be read aloud over a phone call without the usual spelling-out problems. The receiving side offers tab-completion on the codewords, so usually only a few characters have to be typed. And the codes are single-use and do not need to be memorized, which removes the question of what happens if someone captures the code after the fact.
The consequence worth sitting with is that the only thing shared between two strangers is a short phrase of speech. There is no account, no address book entry and no public key to exchange first. For a one-time transfer that is the right trade, because the ceremony is short enough that nobody has to set anything up. For anything recurring, the same property becomes the problem, since there is no identity to attach the transfer to.
Two console scripts and three completion files
The packaging in `setup.py` is worth reading because it answers several small questions at once. The package declares itself for Python 3.10 and newer, and the trove classifiers name versions 3.10, 3.11 and 3.12 alongside CPython as the implementation. The status classifier is `Development Status :: 4 - Beta`, which is the project's own self-assessment and a fair thing to weigh given how widely the tool is already shipped.
The console scripts block registers two entry points pointing at the same callable:
entry_points={
"console_scripts":
[
"wormhole = wormhole.cli.cli:wormhole",
"magic-wormhole = wormhole.cli.cli:wormhole",The inline comment explains the second one: an entry point that matches the package name is advantageous for things like `uv tool run`. That is a small convenience for people who want to run the tool without installing it into an environment, and it also explains why you may see two names in the wild for one program.
Completion is handled with the same belt and braces approach. `data_files` installs `wormhole_complete.bash` into `share/bash-completion/completions`, `wormhole_complete.zsh` into `share/zsh/site-functions`, and `wormhole_complete.fish` into `share/fish/vendor_completions.d`, and all three filenames appear at the top level of the repository tree as generated files. The package list itself covers `wormhole`, `wormhole.cli`, `wormhole._dilation`, `wormhole.test`, and `wormhole.test.dilate`, which is a small hint at the internal split between the CLI, the path that handles poor network conditions, and the test suite.
The two servers you do not get in this repository
This is the fact that most people discover late. The program uses two servers, and their source code is kept in separate repositories: the mailbox server and the transit relay, each under their own project on the magic-wormhole organization. This repository holds the client.
The split is not arbitrary. The mailbox server's job is small and centralized: it knows which wormhole codes exist and relays the initial connection between the two peers. The transit relay is the data path, and the client side of it lives in a package called `wormhole._dilation`, a name that comes from the TCP congestion-control algorithm used to keep the transfer moving over slow or lossy links. If you use the public servers, you are using infrastructure you did not run, which is a dependency worth understanding before you send something over it.
Because the README only links the two server repositories and does not describe either protocol, the documentation site carries the real specification. The README does point at it explicitly, both at readthedocs and at the `docs/` subdirectory, and it also links the PyCon 2016 slides and video, which remain the clearest single explanation of the design that has been published.
Installation is somebody else's job in most cases
The README opens its packaging section by saying magic wormhole packages are included in many operating systems, and links a repology packaging status badge to back that up. Only after that does it say that to install it without an OS package, follow the installation docs. So the primary installation path is a distribution package, not a pip command from this page.
That shapes who this tool reaches. Somebody on a mainstream Linux distribution, macOS or Windows gets it from the package manager, where the version is chosen by the distribution rather than by the project. Somebody on an unusual platform, in a container, or on a locked-down system is the audience for the PyPI route that the installation docs cover. Both paths end at the same README statement about compatibility, which is Python 3.10 and higher, tested against versions up to 3.12.
It is also worth noting what the README does not do. There is no version number printed in it, no upgrade instructions, and no security policy section. The repository has `NEWS.md` as a changelog file and publishes no GitHub releases, so the changelog in the repository is the version history you have. The default branch is `master`, the license is MIT with the details deferred to the `LICENSE` file, the repository is not archived, and the last push was on 2026-09-14.
The Makefile documents how a release is made
The top-level `Makefile` is unusual in a way that is worth reading, because its comment block says it answers the question how to make a release, hopefully better than a document does, and notes that only two maintainers may currently perform the upload to PyPI. That is a candid statement about release bus factor, and it is also a statement that releases are deliberate events rather than continuous publishing.
The everyday targets are small:
lint:
tox -e flake8less
test:
python3 -m pytestThe linter environment is named `flake8less`, which points at how the project handles that particular plugin, and the test target is a plain pytest invocation. The `completions` target regenerates all three shell completion files in one go:
completions:
bash -c '_WORMHOLE_COMPLETE=bash_source wormhole > wormhole_complete.bash'
zsh -c '_WORMHOLE_COMPLETE=zsh_source wormhole > wormhole_complete.zsh'
fish -c '_WORMHOLE_COMPLETE=fish_source wormhole > wormhole_complete.fish'That is where the three completion files at the repository root come from, which is a useful thing to know before you edit one by hand.
The release sequence below those targets is the interesting part. It refuses to start if the checkout is dirty, using `git diff-files` and `git diff-index`, installs the build extras with `pip install --editable .[build]`, validates the README with `setup.py check`, then clear-signs `NEWS.md` with GPG under the maintainer's key before running `update-version.py`. It builds a wheel, detach-signs it, and does the same for the source distribution. Version numbers come from `versioneer.py`, configured in `pyproject.toml` to read from git with a `pep440` style and no tag prefix. The `signatures/` directory in the tree is where those detached signatures live, which means releases are signed artifacts rather than plain uploads.
Where magic-wormhole is the wrong tool
There are three cases where this is a poor fit, and it is better to name them than to describe the tool without boundaries.
First, recurring transfers. Codes are single-use by design and there is no account or identity model in the client, so a scheduled backup or a scripted handoff is not what this is for. For anything unattended, a conventional sync tool gives you retries and a stable destination.
Second, contexts where a relay in the path is unacceptable. Two peers may both be on networks that permit only outbound connections, and the transit relay exists precisely so that the sender uploads and the receiver downloads, which means the bytes may travel through infrastructure you chose to trust. Where a direct path is possible, a peer-to-peer tool is the better answer.
Third, anything needing a user interface. The searches people run for this project keep asking about Android, iOS, Windows and web clients, and those exist only as separate projects or not at all. This repository ships a library and a command-line tool, and nothing in the README promises a graphical front end.
The honest comparison is not with other command-line tools but with the alternatives people actually use. If the two machines are on the same network, an ordinary file share is simpler and has no relay at all. If the recipient has a shell and you have a text channel, `curl` to a temporary host or a paste service may be enough. magic-wormhole earns its place when neither of those is true and you need encryption without anybody creating an account first.
Editorial conclusion
magic-wormhole is at its best as the ninety-second answer to a problem that has stalled: getting a file to someone who is not on your network without opening a port or pasting a base64 blob into chat. The code exchange is genuinely short, tab completion removes the typing burden, and single-use codes mean a leaked code is not a standing credential. What it is not is a general-purpose transfer service, because the mailbox server and the transit relay live in their own repositories and are operational dependencies you now run or trust. If you need a web interface, an Android or iOS client, or scheduled unattended transfers, none of that is in this repository. Start with the Python 3.10 floor and the two-server requirement, then read the documentation site for the mailbox and transit protocols.
Frequently asked questions
What does magic-wormhole use for?
It moves arbitrary-sized files and directories, or short pieces of text, from one computer to another over a short pronounceable code that both sides type. The codes are single-use, and the receiving side offers tab-completion on the codewords so usually only a few characters need typing.
Does magic-wormhole need to be installed on both computers?
The package provides a library and a command-line tool named `wormhole`, and getting a file from one machine to another means running it on the sending machine to generate a code and on the receiving machine to enter that code. It is also packaged by many operating systems, so the install is usually a package manager operation rather than a pip command.
What servers does magic-wormhole rely on?
Two, and their source code is kept in separate repositories under the same organization: a mailbox server that pairs the two peers, and a transit relay that carries the data. This repository holds the client, so the servers are operational dependencies you either run yourself or get from someone else.
What Python versions does magic-wormhole support?
The README states compatibility with Python 3.10 and higher, tested against versions up to 3.12, and the package classifiers list 3.10, 3.11 and 3.12. The trove classifiers also record the project status as Development Status :: 4 - Beta.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/magic-wormhole-magic-wormhole)