Copy photos, videos, documents, and music from your Android phone to your computer over USB — no account, no cloud, no cables except the one you already have.
The app runs entirely on your local machine. Open it via a start script, a browser tab opens automatically, and the server shuts itself down when you close the tab.
- Connect your Android phone via USB
- Run the start script for your platform (see below)
- A browser tab opens at
http://localhost:3000 - Click Scan for device — the app detects your phone automatically
- Choose what to copy: Images, Videos, Files, Music, or All Types
- Optionally filter by date range (images and videos only)
- Pick the source folder on your phone and a destination on your computer — the phone browser opens in the most relevant folder for your chosen file type (DCIM for images/videos, Download for files, Music for music) with shortcut buttons at the top for other common locations
- Click Start Copy — the app scans and copies files, sorted into subfolders by type and date
- Close the tab when done — the app shuts itself down
| Connect | Setup |
|---|---|
![]() |
![]() |
| Setup (date range active) | Transfer |
|---|---|
![]() |
![]() |
| Summary | Summary – files copied detail |
|---|---|
![]() |
![]() |
| Summary – files skipped detail | Summary – errors detail |
|---|---|
![]() |
![]() |
- A computer running Windows, macOS, or Linux
- Node.js installed (v18 or later)
- An Android phone with USB Debugging enabled (the app walks you through this)
- A USB cable
Windows only: Git for Windows is required to run start.vbs. If you already use Git Bash, you have it.
ADB is included. The app downloads Android Debug Bridge automatically on first launch. You do not need to install it yourself.
Download the ZIP from GitHub and extract it anywhere on your computer.
Windows — double-click start.vbs. A terminal window opens, the browser launches, and the terminal closes automatically when you close the browser tab. Use start.bat instead if you want to keep the terminal open for troubleshooting.
macOS / Linux — open a terminal in the folder and run:
./start.shOn first launch the script will:
- Install Node.js dependencies
- Build the app
- Download the ADB tool for your platform (requires internet, one time only)
After that, the browser opens automatically and the app is ready.
The app includes a step-by-step guide on the connect screen, but here is the short version:
- Open Settings → About Phone
- Tap Build Number 7 times until you see "Developer options unlocked"
- Go back to Settings → Developer Options
- Enable USB Debugging
- Connect your phone via USB — tap Allow when prompted on the phone screen
If you are prompted with multiple USB options, choose the one that allows file transfers over USB.
Files are copied into type-named subfolders at the destination you choose:
Destination/
images/
2024/
06/
14/
IMG_4821.jpg
Unknown/
photo_no_date.jpg
videos/
2024/
06/
14/
VID_0032.mp4
files/
report.pdf
notes.docx
music/
song.mp3
| File type | Destination structure |
|---|---|
| Images | images/YYYY/MM/DD/ |
| Videos | videos/YYYY/MM/DD/ |
| Documents & archives | files/ (flat) |
| Audio | music/ (flat) |
For images and videos, the date is read from EXIF data embedded in the file. If no EXIF data is present, the file modification date reported by the phone is used. Files with no date at all go into images/Unknown/ or videos/Unknown/.
Deleted files (items in the phone's trash, e.g. .trashed-*) are automatically excluded and never copied.
| Option | What gets copied |
|---|---|
| Images | .jpg .jpeg .png .heic .heif .webp .gif .bmp .raw .dng .cr2 .nef .arw .orf |
| Videos | .mp4 .mov .avi .mkv .3gp .m4v .wmv .ts |
| Files | .pdf .doc .docx .xls .xlsx .ppt .pptx .txt .rtf .odt .ods .odp .csv .zip .rar .7z .epub .mobi |
| Music | .mp3 .wav .flac .aac .ogg .m4a .wma .opus .aiff |
| All Types | All of the above |
When Images or Videos (or All Types) is selected, you can switch to Date range mode and set a From and To date. Only files whose modification date falls within that window will be scanned and copied.
The Files and Music options always copy all matching files regardless of date — the date range selector is hidden when those types are selected.
If a file with the same name already exists at the destination, a dialog appears:
| Option | Behaviour |
|---|---|
| Skip | Skip this file, continue with the rest |
| Skip All | Skip all remaining conflicts automatically |
| Overwrite | Replace the existing file with the one from the phone |
| Overwrite All | Replace all remaining conflicts automatically |
A Cancel button is shown at the bottom of the screen while files are being copied. Pressing it stops the transfer immediately and shows a summary of how many files were copied before cancelling.
If the USB cable is disconnected at any point after the phone has been detected — on the setup screen or during a transfer — the app shows an error screen explaining what happened. Pressing OK takes you back to the connect screen where you can plug back in and scan again.
If the selected source folder contains no files matching the chosen type (or date range), the app shows a clear message instead of silently completing with zero results. This can happen if:
- The file type does not match the folder (e.g. looking for images inside the Music folder)
- The date range excludes all available files
- The folder is empty
The interface is available in:
- English
- Danish (Dansk)
- Spanish (Español)
Select your language from the dropdown in the top right corner. The choice is saved for future sessions.
To compile this project you need the following installed on your machine:
- Node.js v18 or later — required to run the build scripts and TypeScript compiler
- npm — comes bundled with Node.js
- Internet access —
npm run setupdownloads ADB binaries from Google's servers (one time only)
No other tools are required. ADB does not need to be installed system-wide; the setup script downloads it automatically.
npm install # Install dependencies
npm run setup # Download ADB binaries for all platforms (one time, needs internet)
npm run dist # Compile TypeScript + bundle into self-contained executablesnpm run setup skips the download if ADB binaries are already present in bin/. To update to the latest ADB release, delete the bin/, then re-run:
npm run setup # Re-downloads latest ADB and writes bin/adb-version.txt
npm run dist # Bundles the new binaries and version stamp into the executablesEnd users get the new ADB automatically on their next app launch — the app compares the bundled version against what is already extracted on disk and re-extracts if they differ.
After npm run dist, the release/ folder contains one self-contained executable per platform, named with the current version:
| File | Platform |
|---|---|
amc-v{version}-win-x64.exe |
Windows x64 |
amc-v{version}-macos-x64 |
macOS Intel |
amc-v{version}-macos-arm64 |
macOS Apple Silicon |
amc-v{version}-linux-x64 |
Linux x64 |
Each executable includes Node.js, the app, and the ADB binary for its platform. End users need nothing installed.
Cross-compilation is supported. You can build the Linux executable from Windows, and vice versa —
pkghandles all platforms in a singlenpm run distrun.
npm install
npm run dev # Run with ts-node (requires adb in PATH)src/
server.ts Express + WebSocket server, browser launch, shutdown
adbPath.ts Resolves ADB binary path (bundled or system)
services/
AdbService.ts Wraps adb CLI via execFile
ExifService.ts Reads EXIF date from local files
FileService.ts Local filesystem helpers
TransferService.ts Transfer orchestration and event emission
routes/
device.ts GET /api/device/status, /api/device/browse, /api/device/check
filesystem.ts GET /api/filesystem/roots, /api/filesystem/browse, /api/filesystem/home
transfer.ts POST /api/transfer/start|resolve|cancel
public/
index.html Single-page app
style.css CSS custom properties, no framework
app.js Vanilla JS
i18n/ Localisation strings (en / da / es)
scripts/
setup.js Downloads ADB binaries from Google
rename-release.js Renames pkg output to include version number
docs/
screenshots/ App screenshots used in this README
- Make sure the version in
package.jsononmasteris the version you intend to release - Cut a
release/vX.Y.Zbranch from master - Build, test, and publish the release from that branch
- Tag the tip of the release branch
vX.Y.Z - Bump the version in
package.jsononmasterto the next version (e.g.0.3.0→0.4.0)
master must always carry a version number one step ahead of the latest published release. This prevents master from ever sharing a version number with a release that is already out.
- Copy
public/i18n/en.jsontopublic/i18n/<code>.jsonand translate all values - Add
<option value="<code>">Language Name</option>to#lang-selectinpublic/index.html
- The app runs entirely on your local machine — no data is sent anywhere
- Files are only read from your phone; nothing is deleted or moved on the phone
- ADB binaries are downloaded once from Google's official servers and stored locally
MIT







