Porterage Download

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

Porterage showing a folder of photos on the phone as a grid of thumbnails, with a breadcrumb, search field, sort control and a free-space readout along the bottom. Porterage in list view, showing file names, sizes and dates in aligned columns with folders first.

The app's own window. Placeholder images were staged on the phone so the owner's library stayed out of it; every figure is as captured.

Throughput, measured

Phone → Mac 38MiB/s
Mac → phone 18MiB/s

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

337 files · 3.2 s for 345 the usual way

Small files
59ms

each, across a thousand in a row

Photo library
64s

325 photos · 2 GiB

First listing
25s

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.

  1. 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 file
    Not drained 1 100 msper file

    Same phone, one scale. Drained, a thousand files in a row held that pace; undrained, it wedged for good at roughly 211 objects.

  2. 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 files
    One request per file 3.2 s345 files

    Both 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.

  3. Two files that differ only in case destroy each other

    The phone's storage ignores capitalisation; the protocol does not. So Report.txt and report.txt both 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.

  1. 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

  2. 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

  3. 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 .part file 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.

Ten rows of the file list close up: an icon, the file name, the size in kilobytes, and the date the phone recorded, in aligned columns.
A row is what you drag. Name, size and the phone's own date, in aligned columns — the same rows the window shows, at the size they are read.
  • 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.