There are two easy ways to make a zip on a Mac: right-click a folder in the Finder and choose Compress, or run zip in the Terminal. Both work. The problem shows up on the other end — you send the file to someone on Windows or Linux, and they open it to find a __MACOSX folder full of ._ files, plus a stray .DS_Store. The usual advice online blames the zip command, and that advice is wrong. On macOS 26.5.2 the two methods make different messes, and only one of them creates __MACOSX at all.
Where the __MACOSX folder actually comes from
The __MACOSX folder is created by the Finder’s Compress command, not by the zip command. The Finder runs Archive Utility, which sequesters each file’s Apple metadata — resource forks and extended attributes — into a parallel __MACOSX tree of ._ files. You can reproduce exactly what it does from the command line with ditto, the tool Archive Utility is built on:
$ ditto -c -k --sequesterRsrc --keepParent project archive.zip
$ unzip -l archive.zip
0 project/
5 project/.DS_Store
0 __MACOSX/
0 __MACOSX/project/
163 __MACOSX/project/._.DS_Store
6 project/b.txt
163 __MACOSX/project/._b.txt
6 project/a.txt
212 __MACOSX/project/._a.txt
Every real file gets a shadow ._ entry, and the whole lot is wrapped in __MACOSX. Now the same folder through the command-line zip:
$ zip -r archive.zip project
$ unzip -l archive.zip
0 project/
5 project/.DS_Store
6 project/b.txt
6 project/a.txt
No __MACOSX, no ._ files. The command-line zip stores Apple metadata quietly inside the archive’s extra fields instead of in visible shadow files, so the only junk it adds is the .DS_Store — and that is there only because the folder already contained one. Two problems remain to clean up: the extra fields and the .DS_Store.
The clean way, from the Terminal
Two flags handle both. -X drops the Apple extra fields; the man page describes it as “do not save extra file attributes… uid/gid and file times on Unix.” -x "*.DS_Store" excludes the Finder’s folder-settings files. Together:
$ zip -r -X archive.zip project -x "*.DS_Store"
$ unzip -l archive.zip
6 project/b.txt
6 project/a.txt
That is a clean archive: only the two files, nothing Mac-specific. The -X flag also shrinks the file — on this test folder, adding -X alone took the same archive from 653 bytes down to 445, the difference being the stripped metadata. For anything you are sending to people on other platforms, zip -r -X … -x "*.DS_Store" is the line to remember.
If you would rather use the Finder
Right-click a file or folder and choose Compress — it is the fastest option for a one-off, and if the recipient is also on a Mac, the __MACOSX folder is harmless. macOS itself ignores it on the way back out; the shadow files only look like clutter to people on other systems.
If you want the Finder’s convenience but a clean result, skip Compress and use ditto with the metadata switched off. This produces the same flat archive as the clean zip above:
$ ditto -c -k --norsrc --noextattr --keepParent project archive.zip
--keepParent keeps the top project folder inside the archive so it does not explode loose files into the recipient’s current directory when they extract it.
Cleaning a zip you already have
If the archive is already made — or you received one full of __MACOSX — you do not have to rebuild it. zip -d deletes entries from an existing archive by pattern:
$ zip -d archive.zip "__MACOSX/*" "*.DS_Store"
And when you are the one unpacking a messy archive, tell unzip to leave the junk behind rather than deleting it afterward:
$ unzip archive.zip -x "__MACOSX/*"
Plain unzip archive.zip extracts everything into the current folder; add -d somedir to send it into a specific one, and unzip -l lists the contents without extracting so you can see what is inside first.
Command quick reference
| Goal | Command |
|---|---|
| Clean zip for any platform | zip -r -X archive.zip folder -x "*.DS_Store" |
| Clean zip via ditto | ditto -c -k --norsrc --noextattr --keepParent folder archive.zip |
| Strip junk from an existing zip | zip -d archive.zip "__MACOSX/*" "*.DS_Store" |
| List contents without extracting | unzip -l archive.zip |
| Extract but skip __MACOSX | unzip archive.zip -x "__MACOSX/*" |
| Extract into a folder | unzip archive.zip -d folder |
The short version: the __MACOSX folder is the Finder’s doing, not the zip command’s. Zip from the Terminal with -X and an exclude for .DS_Store, or use ditto with the metadata flags off, and the archive you hand off will look the same on every platform.