FlooTransfer
An FTP/FTPS/SFTP client that lives inside VS Code. I wanted to make a better FTP/SFTP VS Code extension than what's currently out there and that had all the features I wanted.
What it does
- Remote Files tree — browse, download, rename, delete, and set permissions
(octal; SFTP always, not every FTP server) on the server. Right-click a file
or folder for Copy Remote Path, or a folder for Calculate Size (total
size and file count, recursively).
- Local Files tree next to it, mirroring the connection's local folder.
Upload from here, or drag files between the two trees to upload/download (drop
on a folder to land them there). Dragging within one tree moves the file and
keeps the other side in sync. Folders go recursively.
- Transfer a file from anywhere — the Explorer, the editor tab, the editor
right-click menu, or a keybinding. Works on images and other binary files too,
not just text. Turn on
uploadOnSave for a connection to upload automatically
every time you save, instead of (or in addition to) doing it by hand.
- Multiple connections per project — e.g.
Preview and Live pointed at the
same folder. If more than one matches you're asked which to use, then it's
cached for the session. Switch Connection on the tree flips which one is
active, and transfers auto-follow whichever connection they used.
- Activities panel (down by the Terminal) logs every transfer with progress
bars, file sizes, bytes transferred so far, and current speed, pops open on
errors, and lets you cancel something mid-transfer.
- Auto-connect — transfer something without being connected and it just asks
for credentials there and then.
- Open Project (
Cmd/Ctrl+Alt+P, or FlooTransfer: Open Project... from the
Command Palette) — jump straight to any project you've configured a connection
for, without leaving VS Code to dig up the folder yourself. Since connections
are stored globally rather than per-project, this lists every one you've ever
set up; a project with more than one connection (like Preview and Live
above) shows up once, not once per connection. Picking an entry normally
opens it the way VS Code's own window.openFoldersInNewWindow setting says
to; hover an entry and click its window icon to open that one in a new
window regardless. A status bar item also shows whichever project the open
folder matches - click it for the same picker.
Setup
Run FlooTransfer: Add Connection for This Project and it'll walk you through it,
or edit connections.json yourself:
[
{
"name": "Preview",
"protocol": "ftp",
"host": "preview.example.com",
"localRoot": "/Users/you/projects/my-site",
"remoteRoot": "/public_html"
},
{
"name": "Live",
"protocol": "sftp",
"host": "example.com",
"authMethod": "key",
"privateKeyPath": "/Users/you/.ssh/id_ed25519",
"localRoot": "/Users/you/projects/my-site",
"remoteRoot": "/var/www/my-site"
}
]
| Field |
Notes |
name |
Required. Shown when picking a connection; must be unique (it's the cache key). |
protocol |
ftp or sftp (default ftp). FTPS is ftp + "secure": true. |
host |
Required. |
port |
Default 21 for FTP, 22 for SFTP. |
secure |
FTP only — use explicit TLS. |
authMethod |
SFTP only — password (default) or key. |
privateKeyPath |
For authMethod: "key" — absolute path to the key. Passphrase asked each session, never stored. |
localRoot |
Absolute path to the local project. Leave unset to pick manually each time. |
remoteRoot |
Directory shown as the tree root. Default /. |
rememberPassword |
See below. Off by default. |
atomicUploads |
See below. Off by default. |
maxConcurrentTransfers |
See Simultaneous transfers below. Defaults to 2. |
ignore |
See Ignoring files below. Defaults to [".git", ".DS_Store", "node_modules", "Thumbs.db", ".svn", ".hg"]. |
uploadOnSave |
Upload a mapped file automatically every time you save it. Off by default. |
Then hit FlooTransfer: Connect, or just start transferring — it asks for
credentials the first time each connection is used.
Remembering a password
By default nothing is stored. Passwords stay in memory for the session
(flooTransfer.sessionDurationMinutes) and are asked for again after that. If that
gets old, set "rememberPassword": true on a connection (or say yes when the
add-connection command asks). After the next successful login the password goes
into your OS keychain and future connects skip the prompt.
Worth understanding the trade: once it's remembered, the password isn't a gate
any more. Anyone on your unlocked machine can reach that server. Same deal as
"remember me" anywhere else, which is fine if you trust the machine and lock your screen. FlooTransfer: Forget Saved Password for Connection
clears a stored one.
On Linux this needs a Secret Service provider running (most desktops have one,
headless/Remote-SSH usually don't). Without it, it quietly falls back to asking
every time.
SFTP host keys
The first time you connect to an SFTP server, FlooTransfer shows you its host
key fingerprint and asks you to trust it, then remembers that fingerprint for
next time - so if a server's key ever changes unexpectedly (which can mean
someone's intercepting the connection, though it can also just mean the
server was reinstalled) you get a clear warning instead of silently connecting
to whatever's on the other end. This is FlooTransfer's own store, not your
system's ~/.ssh/known_hosts - the two are independent.
If you reinstall or re-key a server on purpose, run FlooTransfer: Forget
Known Host Key first so the next connect treats it as trusted again instead
of warning you every time.
Atomic uploads
Normally an upload writes straight to the real filename as bytes arrive, so a
file that's already live can be served half-written for a second. With atomic
uploads the file goes to a temp name first and is renamed into place once it's
fully there. A rename is instant, so the real filename only ever points at a
complete old or complete new version.
- Per connection:
"atomicUploads": true applies it to every upload on that
connection, including each file in a folder upload. Each file is safe on its
own, but a multi-file upload still swaps them in one at a time.
- Batch: for a set of files that should go live together use
FlooTransfer: Add to Atomic Upload Batch (right-click, or the keybinding on the
active tab), review the list in the Atomic Upload
Batch view, then FlooTransfer: Upload Atomic Batch. Everything uploads to temp
names and only gets renamed into place once all uploads finish, back to back.
So the "half new, half old" window is a fraction of a second instead of the
whole upload.
Caveat: not every FTP server allows renaming over an existing file. SFTP almost
always does (FlooTransfer uses posix-rename@openssh.com). If the rename fails you
get an error saying the upload succeeded and where the temp file is.
Simultaneous transfers
Uploading or downloading a folder (or a batch) runs more than one file at a
time - each one over its own connection, the same idea as FileZilla's
"maximum simultaneous transfers". It defaults to 2, matching FileZilla's
own default, which comfortably fits under the connection limit most FTP/SFTP
hosts allow.
Set "maxConcurrentTransfers" on a connection to change it - raise it if
that server tolerates more concurrent connections, or drop it to 1 to go
back to one-at-a-time if a server is stricter (you'll see connection-refused
style errors if you've gone too high). It only affects how many files move
at once; one large file is still a single stream either way.
Ignoring files
Uploading or downloading a folder skips a handful of things by default -
.git, .DS_Store, node_modules, Thumbs.db, .svn, .hg - since almost
nobody actually wants those copied to or from a server. Set "ignore" on a
connection to change the list: [] transfers everything, or your own list of
patterns replaces the default entirely (it doesn't merge with it).
Patterns use */? wildcards and match by name against any file or folder
in the path, at any depth - "node_modules" skips a folder with that exact
name wherever it appears, "*.log" skips any matching file wherever it
appears. This isn't a full .gitignore-style path glob (no anchoring a
pattern to a specific nested location, no negation) - just "always skip
anything named like this."
Keyboard shortcuts
| Action |
Shortcut |
| Upload |
Cmd/Ctrl+Shift+S |
| Download |
Cmd/Ctrl+Alt+D |
| Rename on remote |
Cmd/Ctrl+Alt+R |
| Delete from remote |
Cmd/Ctrl+Alt+Backspace |
| Add to atomic upload batch |
Cmd/Ctrl+Alt+B |
| Upload atomic batch |
Cmd/Ctrl+Shift+Alt+B |
Cmd/Ctrl+Shift+S is also VS Code's Save As. When the file you're editing
belongs to a connection, this shortcut uploads it; anywhere else it falls
straight through to Save As, so nothing's lost.
Rebind them in Preferences: Open Keyboard Shortcuts if they clash with
anything.
Settings
| Setting |
Default |
Notes |
flooTransfer.sessionDurationMinutes |
60 |
Minutes an entered password stays in memory. 0 = whole session. |
flooTransfer.progressBarColor |
#007ACC |
Any CSS color. |
flooTransfer.activitiesSortOrder |
newestFirst |
newestFirst or oldestFirst. |
flooTransfer.remoteSortDirection |
ascending |
Name sort in both trees. Folders always above files. |
Limitations
- Atomic uploads protect each file, not a whole multi-file deploy as one instant
switch. Also the rename step isn't supported by every FTP server.