Android files on your Mac, straight off the cable.
Porterage speaks the phone's transfer protocol itself instead of going through the usual library. That is the whole reason the numbers on this page are not the ones you are used to.
Version 0.1.1 · free and open source · macOS 14 or later · Apple silicon and Intel · 2.1 MB · no dependencies
Not notarised by Apple yet, so macOS blocks the first launch. How to get past that, and what else it does not do
Throughput, measured
040 MiB/s full scale
Both bars share one scale. The limit on the way in is the phone's own flash, not the cable.
- Folder listing
- 0.4s
- Small files
- 59ms
- Photo library
- 64s
- First listing
- 25s
337 files · 3.2 s for 345 the usual way
each, across a thousand in a row
325 photos · 2 GiB
once, while the phone indexes
Three ways the other tools fail
Each one was reproduced on a Redmi 9T against a MacBook Air M1, and each is the reason a corresponding part of Porterage is built the way it is.
-
It stops answering after a couple of hundred files
The phone raises an interrupt event for every object written. A client that never reads that queue slows down as the queue fills, and then MTP stops responding entirely — a USB reset does not recover it. You have to physically unplug the cable.
Queue drained 59 msper fileNot drained 1 100 msper fileSame phone, one scale. Drained, a thousand files in a row held that pace; undrained, it wedged for good at roughly 211 objects.
-
Opening a folder takes longer than it should
The common library marks every Android device as unable to use MTP's bulk listing command, and offers no way to override it — so it asks the phone about each file in turn. Porterage implements the protocol itself and asks once per property instead.
Porterage 0.4 s337 filesOne request per file 3.2 s345 filesBoth bars share one scale. Two folders of nearly the same size on the same phone: 337 files through Porterage, 345 through the one-request-per-file route, measured on the earlier prototype. At ten thousand photos that is about 95 seconds against twelve.
-
Two files that differ only in case destroy each other
The phone's storage ignores capitalisation; the protocol does not. So
Report.txtandreport.txtboth appear in a listing while sharing one file underneath, and writing the second silently overwrites the first. Nothing warns you. Porterage checks every name against the files already on the phone the way the storage does, and stops to ask before anything is written.Silently overwritten elsewhere
Stopped here, with the conflicting name shown
Keep Both, Replace or Skip — asked once for the whole drop, before a byte is written.
Every tile in the grid gets a picture
MTP's thumbnail command is not a thumbnail service. It hands back whatever the file's own EXIF header already holds — which, for a screenshot or a downloaded image, is nothing. So there are three routes, tried in that order, and the grid fills instead of showing blanks.
-
Route 1
Ask the phone
The embedded thumbnail, sent straight off the phone. Camera photos almost always carry one.
36 ms each · every one of 60 camera photos tried · 300 photos in about 11 s
-
Route 2
Read the first 64 KiB
When the phone returns nothing, pull the header down and look for the embedded JPEG there.
Found one in 17 of the 20 tried
-
Route 3
Fetch it and scale it on the Mac
The whole file, resized on this end. Screenshots and downloaded images land here.
About 15% of a real phone · files over 40 MiB skipped
The whole pass runs after every visible tile already holds something, so scrolling is never waiting on a picture.
What it does when things go wrong
Interruption is the normal case with a cable. It is designed for, not apologised for.
-
The cable comes out mid-copy
A copy to the Mac is written as a
.partfile and takes its real name only once the last byte lands, so nothing half-finished ever looks finished. Copy it again into the same folder and it continues from the bytes already there instead of starting over..part until the last byte · copy again to continue
-
The screen locks while copying
A locked phone hands over an empty storage list, which other tools report as nothing more specific than “not connected”. Porterage names the lock instead, and reconnects once the phone is unlocked, so copying to the Mac again picks up from the bytes that already arrived. Whether a lock stops a copy that is already running is not settled, so the advice below stays the cautious one.
Keep the phone unlocked until the copy finishes
-
The phone is nearly full
The phone itself will happily accept a file far larger than its remaining space and fail minutes later. Its reported free space, though, is exact to the byte — so Porterage checks the whole drop first and tells you how much is missing.
64 MiB written moved free space by 64.1 MiB, and back on delete
And when nothing shows up at all
A locked phone, one set to Photo transfer, another app holding the port, nothing connected, and a phone that has stopped answering all look different on the wire. Each gets its own name and its own instruction, in the app's own words, instead of “busy or not connected”.
-
No phone found
Many charging cables carry power only — and the phone has to be set to File transfer.
-
The phone isn't sharing its storage
Unlock the screen — the window fills in by itself. If it is already unlocked, choose File transfer again.
-
A device is connected in Photo transfer mode
In Photo transfer mode a phone shows only its photo folders. Switch it to File transfer.
-
Another program is holding the phone
Quit any other phone manager — OpenMTP, Android File Transfer — and try again.
-
The phone is connected but not answering
Once a phone stops answering, only a replug brings it back — restarting the app is not enough.
Drag a row straight into the Finder
The file is fetched when you let go, not when you pick it up. Start the drag on a large photo and it moves with the cursor immediately; the copy happens once the drop lands somewhere. Drop files the other way, copy whole folders in either direction, and watch the free space on the phone move as it happens.
- Rename, and delete behind a confirmation
- New folder, select all
- Search that ignores accents
- Space bar to preview a photo, arrows to step
- A thousand files deleted in 9.5 s, in one command
- Stopping a copy takes a third of a second, and leaves nothing
Conditions of measurement
One phone, one Mac, one cable. Your hardware will differ — these are the conditions the numbers above were taken under, not a promise about yours.
- Phone
- Redmi 9T, MIUI, Android 11
- Computer
- MacBook Air M1, macOS 26.5.1
- Build
- Porterage 0.1.1, the same one on the download button
- Sustained
- A thousand small files, 325 photos and a 4.2 GB file back to back, no errors and no drift
- Large files
- 4 404 019 200 bytes sent and read back, identical byte for byte by SHA-256
- First listing
- About 25 s after unlocking, while the phone indexes ~34 000 objects. Every listing after that, 0.4 s
What it does not do
Stated here because finding out later is worse.
-
Not signed by Apple yet.
macOS refuses the first launch until a Developer ID certificate is in place, and since Sequoia the old Control-click shortcut no longer works. Double-click Porterage once and let it be blocked, then go to System Settings → Privacy & Security, scroll to Security, and click Open Anyway — the button appears there for about an hour after the attempt. It asks for your password once, and never again.
-
No Wi-Fi, no cloud, no account.
A cable, and nothing to switch on inside the phone. The two apps most often suggested instead do work without a cable — and both begin by telling you to unlock Developer Options and turn on USB debugging. That is the trade, stated in both directions.
-
Dates survive one direction only.
Files copied to the Mac keep their original date; the phone stamps its own clock on anything copied to it, and refuses to be told otherwise.
-
Memory cards are not read.
Only the phone's first storage is listed, so a microSD card does not appear. The phone used for development has no card slot in use.
-
0.1.1 is early.
One phone model has been tested properly. If yours behaves differently, the connection report in the app is designed to say why.
Plug the phone in and see what it says.
Free, open source, and 2.1 MB. If it cannot reach your phone it will tell you which of the five states it is in, and what to do about it.