PrintDrop
Open source · Local first · No cloud

Drop a print job from your desk.

PrintDrop plugs into your printer's USB port and appears as an ordinary flash drive — while also serving a web UI over Wi-Fi. No cloud, no account, no firmware changes.

Runs on a 4 MB ESP32-S3. Built for printers that only accept USB media.

printdrop.local
media online
$ printfd status
bus   sdio 4-bit @ 20 MHz · fat32 — projected
wifi  printdrop.local · 192.168.1.42
lock  idle · printer owns the card

benchy.gcode

20 MB · uploaded at ~2 000 KB/s · SDIO 4-bit

ready
Withdrawn from the printer while writing, remounted after

~3 200

KB/s card read — SDIO

~2 000

KB/s card write — SDIO

62

KB web UI, self-hosted

~6 s

20 MB job — SDIO (was ~80 s SPI)

SDIO 4-bit — at 20 MHz (stable on jumper wiring) delivers ~3 500 KB/s raw, ~3 200 KB/s USB read and ~2 000 KB/s USB write — a 20 MB job lands in ~6 s instead of ~80 s on SPI (485 KB/s read / 248 KB/s write). SDIO 4-bit at 40 MHz reaches ~6 000 KB/s raw on short wiring. The old SPI path remains available as -e printdrop_spi. The card, not the network, was the limit — SDIO removes it.

Why PrintDrop

The errand the USB stick keeps creating.

Plenty of 3D printers accept jobs only from USB media and have no networking of their own. Every print becomes the same errand: slice at your desk, copy to a stick, carry it across the workshop — then somebody else needs the stick.

An ordinary flash drive
A USB mass storage device with a FAT32 volume. As far as the printer is concerned, nothing unusual is plugged in.
A web UI over Wi-Fi
Drag a .gcode file onto the page from any browser. Progress, transfer rate and estimated time are shown per file.
Local only
Wi-Fi credentials live in the device's NVS. Nothing leaves your network, and there is no service to sign up for.
How it works

Drop. Hand back. Print.

PrintDrop holds the card, serves it to both sides, and never lets them collide. While a file arrives over Wi-Fi the media is withdrawn from the printer; when the write is done it is re-presented, and the new job is simply in the menu.

[desk]     drop benchy.gcode → web ui
[device]   media withdrawn · writing 20 MB
[device]   write done · media re-presented
[printer]  FAT re-read · job in the USB menu
01
Upload from your desk
Drag a .gcode file onto the web UI. Progress, transfer rate and estimated time are shown per file.
02
The card is handed back
PrintDrop briefly withdraws the media from the printer while it writes, then re-presents it. The printer re-reads its file list.
03
Walk over and print
The file appears in the printer's own menu, exactly as if it had been copied from a USB stick.
Inside the device

Small parts. No surprises.

A 4 MB, no-PSRAM ESP32-S3 drives an SD card over SDIO 4-bit at 20 MHz (40 MHz with short wiring) and presents it through TinyUSB mass storage — ~4× the SPI bandwidth on the same breakout plus two wires, ~6× at 40 MHz. SPI remains available as -e printdrop_spi. The UI is 62 KB of plain HTML, CSS and JavaScript served from a LittleFS partition — no CDN, no external requests, no build step.

Hardware notes
ESP32-S3TinyUSB MSCSD over SDIO (4-bit)FAT32LittleFSNVSNo PSRAMOne lockLocal only
Correctness

One card. Two masters.

A USB host caches the file allocation table. Writing to the card behind its back is how these devices normally corrupt themselves. PrintDrop holds to three rules.

One lock
Every access to the card, from either side, is serialised.
Withdraw before writing
The media is taken away from the printer for the duration of a write, then handed back so it re-reads the table.
Remount when the host writes
If the printer changes sectors, the device throws away its own cached view before trusting it again.

Mass storage callbacks take the lock with a short timeout and fail the transfer rather than block, so a slow upload can never stall a printer mid-job.

Your browser
Drag a .gcode onto the page
ESP32-S3
TinyUSB MSC · Wi-Fi
SD card
FAT32 · one lock
Your printer
Reads its USB menu
The experience

Five small pieces, one coherent UX.

Live progress over WebSocket, a heartbeat LED you can read across the room, zero-config discovery that actually works on Windows, a login that lives in NVS, and an OTA path that survives a bad flash — all on the same 4 MB stick.

WebSocket progress
ws://:81 pushes upload progress and status — no 5 s poll, every client sees the same bar.
LED + button
Idle 2 s heartbeat, activity fast blink, error double-blink. Short press = eject, 5 s = factory reset.
mDNS + LLMNR
http://printdrop.local (mDNS) and http://printdrop (LLMNR) — Windows without Bonjour still finds it.
Web UI auth
HTTP Basic, SHA-256 in NVS, seed from ini, change via serial auth or Settings.
Dual OTA
POST /api/ota with .bin or drop firmware.bin+.json on SD — dual 1 344 KB slots on 4 MB.
Documentation

Every detail, written down.

Stop carrying a stick across the workshop.
Flash an ESP32-S3, plug it into the printer's USB port, and drop jobs from any browser on your network.