beam
Send a whole project to someone else's laptop, wherever they are, from the
terminal. You upload and walk away; they pick it up whenever they like. The zip
includes a start.bat: they double-click it and the project is set up and
running, with no manual installs.
Laptop A — here, now:
beam send D:/projects/my_app
# uploading to x0.at ...
# code : xEGsg-gbDICMBKMQ69BmvI
Close the laptop. Send the code however you like — WhatsApp, email, a chat message.
Laptop B — another city, tomorrow:
beam receive xEGsg-gbDICMBKMQ69BmvI
# saved to .\my_app.zip
# unzipped into .\my_app
That is the whole thing. The other person never writes a line of Python and
never has to be online at the same time as you: they pip install beam-lan
and type the code.
Python 3.9+. Works on Windows, macOS and Linux (start.bat is for Windows).
Install
On both laptops:
pip install beam-lan
If your shell says beam: command not found afterwards, Python's scripts
folder is not on your PATH. Use python -m beam instead — it is the same
command:
python -m beam send D:/projects/my_app
python -m beam receive xEGsg-gbDICMBKMQ69BmvI
Send a project
beam send D:/projects/my_app # the project folder
beam send D:/projects/my_app -x .mp4 -x .log # leave file types out
beam send D:/projects/my_app --main app.py # what start.bat runs
beam send report.pdf # a single file, sent as it is
It zips the folder, encrypts it, uploads it and prints a code. That is the end of your part — the file waits on the host until the other person fetches it.
To send a file you already have, such as a zip or a PDF, pass its path instead of a folder. It is sent as it is.
Receive it
beam receive <code> # saves my_app.zip here and unzips it
beam receive <code> -o D:/Downloads # somewhere else
beam receive <code> --no-extract # keep the zip, do not unzip
An existing my_app.zip is never overwritten: the new one becomes
my_app (1).zip unless you pass --overwrite.
How long it is kept
The encrypted zip goes to the first free host that will take it. Which one you
get depends on the size and on who is up; beam send says which it used and
how long the code is good for.
| Host | Up to | Kept for |
|---|---|---|
| x0.at | 225 MB | at least 30 days |
| catbox.moe | 200 MB | until catbox removes it |
| uguu.se | 128 MB | 3 hours |
| temp.sh | 4 GB | 3 days |
If one is down or blocked, beam moves to the next. For anything over 8 MB it pokes each host with a few bytes first, so a host having a bad day costs a round trip rather than your whole upload.
These are free public services with no promises attached. If they are all
unreachable, beam pack makes the zip and you share it another way.
Your own relay
Depending on strangers' servers is the weak point above. relay/ is a small
Cloudflare Worker you can deploy to your own account in about five minutes; it
keeps the encrypted zip in R2 and its expiry in Upstash Redis.
export BEAM_RELAY=https://beam-relay.<your-subdomain>.workers.dev
beam send D:/projects/my_app # goes to your relay, not to x0.at
Compared with the public hosts it is:
- yours — nobody else's uptime, rules or country blocks
- short-lived on purpose — a TTL you set, 5 hours by default, to the second
- burn-after-read — deleted the moment the receiver confirms the zip decrypted intact, rather than sitting there until it expires
beam tries your relay first and falls through to the public hosts when it is
unreachable, so a relay that is down slows things rather than breaking them.
Codes from a relay start with w, and the receiver needs BEAM_RELAY set too
unless you bake the URL into your own build.
Setup, settings and the rate limits are in relay/README.md.
Same network? Skip the upload
When both laptops are on one local network and both are on right now, --lan
hands the file straight across. Nothing is uploaded, no internet is needed, and
there is no size limit.
beam send D:/projects/my_app --lan # prints a short code, e.g. ab3f9c
beam receive ab3f9c # on the other laptop
beam send --lan waits until the other laptop has the file, so both people
have to be at their machines. "Same network" means the same Wi-Fi, a cable into
the same router, or a phone hotspot they have both joined.
beam receive tells the two kinds of code apart by itself: --lan codes are
short and have no dash, so you never say which one you are using. If discovery
fails on a locked-down network, use the address the sender printed:
beam receive ab3f9c --host 192.168.1.42:8765
Only make the zip
beam pack D:/projects/my_app
beam pack D:/projects/my_app -o D:/share/app.zip -x .csv
What goes in the zip
- Your files, minus things that should not travel:
.venv,venv,__pycache__,.git,node_modules,.env(secrets) and similar caches. Virtual environments do not work when copied to another computer;start.batbuilds a fresh one instead. - What you excluded.
".mp4","mp4"and"*.mp4"all skip mp4 files. A plain name such as"data"skips a file or folder with that name. A.beamignorefile in the project adds more patterns, one per line. start.bat, which does the setup and starts the project.requirements.txt. Your own is used if the project has one. Otherwise beam reads the project'simportlines and writes one (for exampleimport cv2becomesopencv-python). Passrequirements=["flask", "numpy"]tobeam.sendto set the list yourself.
What start.bat does
| Project | start.bat |
|---|---|
Python (main.py, app.py, run.py, ... or main=) |
creates .venv, installs requirements.txt, runs the script |
| Streamlit app | same setup, then streamlit run app.py |
Django (manage.py) |
same setup, then manage.py runserver |
Node (package.json) |
npm install, then npm start |
Website (index.html) |
opens it in the browser |
The setup runs once. After that, start.bat goes straight to starting the
project. If Python or Node.js is missing, it says where to download it. To
start over, delete the .venv folder.
Turn it off with --no-start-script.
Who can read it
- The zip is encrypted on your laptop with AES-256-GCM, using a random key.
- Only the encrypted file is uploaded. The key never leaves your laptop.
- The code is
<where it is>-<the key>, so the host only ever stores unreadable bytes — it cannot see your file names or your code. receivedownloads it, checks it has not been altered, and decrypts it.
Anyone holding the whole code can download and decrypt the file, so send the code only to the person it is for. Treat it like a password, not a link.
The free hosts are public: the encrypted file sits there until it expires (and
on catbox, until catbox removes it). If you need it gone on a schedule, use
--lan or beam pack.
All options
beam send <folder>
| Option | Effect |
|---|---|
-x, --exclude PATTERN |
file type or name to leave out; repeat it, or use commas |
--main SCRIPT |
script that start.bat runs (default: auto-detected) |
--no-start-script |
do not add start.bat / requirements.txt |
--max-size-mb MB |
leave out files bigger than this |
--lan |
hand it straight over on the local network instead of uploading |
--cloud |
upload — the default, so this only spells it out |
-q, --quiet |
print nothing |
--lan only: --code CODE picks the code yourself, --port N sets the port
(default 8765, another free one if taken), --timeout SECONDS gives up if
nobody connects.
beam receive <code>
| Option | Effect |
|---|---|
-o, --out FOLDER |
where to save (default: here) |
--no-extract |
keep the .zip, do not unzip it |
--overwrite |
replace what is there instead of adding (1) |
-q, --quiet |
print nothing |
--lan codes only: --host IP[:PORT] skips searching the network, and
--wait SECONDS sets how long to search (default 15).
beam pack <folder>
Same as beam send minus the network options, plus -o, --output ZIP.
From Python
The command line is a thin wrapper over beam.send, beam.receive and
beam.pack.
import beam
code = beam.send("D:/projects/my_app", exclude=[".mp4"]) # uploads
beam.receive(code, extract=True) # on the other laptop
beam.send("D:/projects/my_app", lan=True) # local network
beam.pack("D:/projects/my_app") # only make the zip
beam.send(path, ...) and beam.pack(path, ...)
| Option | Default | Effect |
|---|---|---|
exclude |
none | file types or names to leave out |
main |
auto | script that start.bat runs |
start_script |
True |
add start.bat (and requirements.txt if needed) |
requirements |
auto | pip packages start.bat installs |
use_default_excludes |
True |
skip .venv, .git, __pycache__, ... |
max_size_mb |
none | skip files bigger than this |
quiet |
False |
print nothing |
beam.pack only: output sets where the zip goes (default <folder>.zip
next to the folder).
beam.send only: lan=True sends over the local network instead of uploading.
With lan=True, code picks your own code, timeout sets how many seconds to
wait for the other laptop, and port sets the network port.
beam.receive(code, ...): out sets the folder to save into, extract also
unzips it, and overwrite replaces existing files. For lan codes, host="IP"
or host="IP:port" skips the search and wait sets how many seconds to
search (default 15).
Errors raise beam.BeamError. The command prints them and exits with 1.
Troubleshooting
beam: command not found: Python's scripts folder is not on your PATH.
Use python -m beam ... instead, or add the folder pip named when it installed
the package.
this code came from a beam relay, but no relay is set here: the sender
used their own relay. Set BEAM_RELAY to the same URL they used.
upload failed on every host: every host was down, blocked, or too small
for the file. The message lists what each one said. Some of these hosts are
blocked in some countries and on some office networks — a different connection
often fixes it. Otherwise use beam pack and share the zip another way, or
--lan if you are both on one network.
nothing found for this code ... expired: the file outlived its host's
retention (see the table above), or the code was not copied completely. Send it
again.
could not decrypt: wrong code: part of the code is missing or mistyped.
Codes are case-sensitive.
no sender with code ... found on this network (--lan only)
- Both laptops have to be running beam at the same time.
- Check they are on the same local network. Guest, office and "public" Wi-Fi often block devices from seeing each other; a phone hotspot both laptops join usually works.
- On Windows, click Allow when the firewall asks about Python on the sending laptop.
- Use the address the sender prints:
beam receive ab3f9c --host 192.168.1.42:8765.
Limits
- Without a relay of your own, the upload depends on free third-party hosts.
They can change their rules, go offline or block your country without notice;
beam tries four of them, but it cannot promise any is up. Deploying
relay/is the fix. - Files over 4 GB, or over 225 MB when temp.sh is down, have to go by
--lan. --lanneeds both laptops on at the same time, on the same local network.start.batis for Windows. On macOS or Linux, unzip the file and installrequirements.txtyourself.
Development
pip install -e ".[dev]"
pytest
ruff check .
python -m build
cd relay && npm test # the Worker; needs node, no account or network
License
MIT
Metadata
Release files for beam-lan 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| beam_lan-0.3.0.tar.gz | 39.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| beam_lan-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 71.5 kB
Release files / beam_lan-0.3.0.tar.gz
| Download URL | beam_lan-0.3.0.tar.gz |
|---|---|
| Size | 39.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7d3d9ae75c2995240d539e825a7b91586f1d69de74686156151a445584f28e38
|
|
BLAKE2b-256 checksum How to use checksums |
9fcaaae975dbbf05ddd69bb7342903719116c6efe71a2993a4d84e960cfead41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / beam_lan-0.3.0-py3-none-any.whl
| Download URL | beam_lan-0.3.0-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5636de606829edf6f91e03fdf36f885c800f213cb0e07729a4b8fdc6cfc5a4cd
|
|
BLAKE2b-256 checksum How to use checksums |
8d655ea2bc803e0f94832cfba1ef7227bfb5c7a669084ebfbb88ce1012207573
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|