The classic loop for editing a site that lives on an FTP server is save, switch to the FTP app, find the file, drag it across, switch back, reload the browser. Twenty times an hour. Auto-upload on save removes the middle: you work in a local copy, and every file you save is sent to the same place on the server.
It’s a different thing from editing a remote file directly, which opens one file from the server and writes it back. Auto-upload watches a whole local folder — the project you already have open in your editor — and mirrors your saves outwards.
How it works, whatever tool you use
Every implementation does the same three things:
- Watches a local folder. On macOS this goes through FSEvents, the same file-system notification service Spotlight and Time Machine use, so it costs nothing while you’re not saving.
- Maps it to a remote folder.
~/Sites/client/wp-content/themes/acme/locally corresponds to/public_html/wp-content/themes/acme/on the server. A file atcss/main.cssunder one goes tocss/main.cssunder the other, and missing folders are created on the way. - Uploads what changed. Only the files the system reports as modified, not a comparison of the whole tree — which is why it’s quick even on a large site, and why it isn’t a replacement for a full folder sync.
The details are where the tools differ, and where it can go wrong.
The traps
Temporary files. Many editors save “atomically”: they write index.php.sb-1234 or .index.php.swp, then rename it over the original. A naive watcher uploads the temp file, leaves junk on the server, or uploads a half-written file. A good one waits a moment for the save to settle and ignores known temp names.
Things that should never go up. .git/, node_modules/, .DS_Store, your local .env. Every tool needs an exclude list, and you should check it before the first save, not after.
Deletions. If you delete a file locally, should it disappear from the server? It sounds logical, but a git checkout of another branch or an editor’s atomic save also “deletes” files for a fraction of a second. Propagating deletions automatically is how a production file vanishes. The safe default is to never delete remotely and to clean up by hand, or with a sync run whose preview you’ve read.
Working on production. Every save is live. A syntax error in functions.php takes a WordPress site down the moment you press ⌘S. Auto-upload is ideal for a staging server; on production, keep it for small changes you’re sure about.
Option 1: an editor extension
If you live in one editor, its extension is the most integrated option.
- VS Code — the popular “SFTP” extension reads a
.vscode/sftp.jsonfile with host, protocol, remote path and"uploadOnSave": true. It handles FTP and SFTP, andignoretakes glob patterns. - JetBrains IDEs (PhpStorm, WebStorm) — Tools ▸ Deployment ▸ Configuration defines the server and path mapping. “Upload changed files automatically to the default server” then sends files on save or on explicit save action.
- Sublime Text and Nova have equivalent plug-ins or built-in publishing.
The downside: the configuration lives inside each project and each editor. If you switch editors, or edit the occasional image in Pixelmator, those saves don’t go anywhere.
Option 2: a script with fswatch
For the do-it-yourself route, fswatch (brew install fswatch) reports changes and lftp or rsync does the transfer:
# Push changed files over SFTP whenever something under ./site changes
fswatch -o ./site | while read _; do
lftp -e "mirror -R --only-newer --exclude-glob .git/ ./site /var/www/html; quit" sftp://deploy@example.com
done
It works with any editor, and for an SSH server rsync is even better. But each change runs a mirror of the whole tree, passwords end up in scripts or need extra setup, and you have to handle exclusions and errors yourself.
Option 3: a file transfer client with auto-upload
A client that already has the connection, the credentials and a transfer queue can do the watching too, independently of the editor you use.
In Upstream, connect to the site, open the local folder in the left pane and the matching remote folder in the right pane. Then turn on Auto-upload on Save from the Transfers menu (⌃⌘U). From then on:
- every file saved under that local folder goes into the normal transfer queue, so you see it upload, with speed and retries, and it ends up in the transfer history;
- editor temp files (Vim, Emacs, Office, TextEdit and Xcode atomic saves,
.DS_Store) are skipped, and so is anything matched by your.syncignore— by default hidden folders like.git/, plusnode_modules/; - missing remote folders are created before the files;
- nothing is ever deleted on the server;
- it switches itself off when you disconnect, so it never sends files to a server you forgot was open.
It works over FTP, FTPS, SFTP and S3 buckets alike. Auto-upload is part of Upstream FULL, with a free 7-day trial.
Step by step
- Get a local copy that matches the server — download the folder once, or start from your project’s repository. The two trees must have the same structure.
- Exclude what must never go up — put a
.syncignore(or your tool’s equivalent) in the local root with.env, build caches and anything private. - Point both sides at the same folder — local theme folder on one side, remote theme folder on the other. A mismatch here uploads files to the wrong place.
- Turn auto-upload on and save one file — check it arrived where you expected before you start real work.
- Run a full sync now and then — auto-upload only sees saves made while it’s running. Files changed by a
git pullwhile it was off need a folder sync with a preview.
Questions people ask
What’s the difference between auto-upload and folder sync?
Auto-upload sends only the files you save, as you save them, and never deletes anything remotely. Folder sync compares the whole local and remote trees on demand, and can also delete or download. Use auto-upload while working and sync to reconcile everything afterwards.
Does auto-upload work with SFTP and S3, or only FTP?
It depends on the tool. Editor extensions usually support FTP and SFTP; Upstream supports FTP, FTPS, SFTP and S3-compatible buckets with the same switch.
Will deleting a file locally delete it on the server?
In most tools only if you enable it, and you usually shouldn’t. A branch switch or an editor’s atomic save briefly removes files, and syncing those deletions can wipe production files. Upstream never deletes on the server through auto-upload.
Why did a .swp or .tmp file appear on my server?
Your watcher uploaded an editor temp file before it was renamed. Add the patterns to the exclude list (*.swp, *.tmp, *~), or use a tool that ignores temp files and waits for the save to finish.
Is it safe to auto-upload to a live website?
For CSS, templates and content, usually. For PHP or configuration files, a typo becomes a live error the moment you save. Work against a staging copy when you can, and keep the server’s backups current.