A professional-grade FTP/SFTP client extension for Visual Studio Code and all its forks (Cursor, Antigravity, etc.) with comprehensive file management capabilities.
- SFTP (SSH File Transfer Protocol) - Port 22 - Encrypted & Secure
- FTP (Standard File Transfer Protocol) - Port 21 - Basic/Unencrypted
- FTPS (FTP over SSL/TLS) - Port 21 - Secure with certificates
- Quick Protocol Switch: Change protocols without re-entering credentials
- Upload on Save: Automatically upload files when saved
- Download on Open: Save files opened from the Remote Explorer into your project
- Connection Profiles: Switch between multiple server configurations
- Multi-Connection Support: Connect to multiple servers simultaneously
- Target Connection Selection: With several connections, choose once where transfers go – no more silent uploads to the first server
- Connection Hopping: Connect through intermediate (jump) servers
- File Watcher: Monitor local files for changes and auto-upload
- Advanced Settings Form: Manage every connection setting from the Connections panel, with (?) help tooltips and examples
- Full File Operations: Upload, download, delete, rename, duplicate files and folders
- Recursive Operations: Upload/download entire directory trees
- File Details: View file size, permissions, and modification date
- File Icons: Native VS Code file type icons
- Hidden Files: Option to show/hide hidden files (dotfiles)
- Copy Path / Copy Relative Path: Copy remote paths from the Remote Explorer (multi-select supported)
- Remote-to-Remote Transfer: Copy files between different remote servers
- Edit in Local: Edit remote files in a temp directory with auto-upload on save
- Sync with Preview: Sync local → remote, remote → local, or both – only changed files, reviewed before anything is transferred or deleted
- Compare Folders: See modified / only-local / only-remote files side by side with the server, diff them and fix differences one by one
- Upload to Multiple Servers: Deploy the same files to staging and production in one step, or to all servers
- Preserve Timestamps: Transferred files keep their modification time, so change detection stays accurate
- Upload Changed Files: Upload only files changed in git
- Permission Management: Change file permissions (chmod)
- Checksum Verification: Calculate and compare MD5, SHA1, SHA256 checksums
- File Information: Detailed file metadata display
- Remote Search: Search content within remote files
- Backup Creation: Create backups of remote files/directories
- Folder Comparison: Compare local and remote folders (split-view panel)
- Quick Search: Ultra-fast file search by name in new tab (parallel traversal, wildcard patterns)
- Search & Replace: Find and replace text across remote files
- Cache Purge: Clear common cache directories on remote server
- Diff View: Compare local and remote file versions
- Compare Remotes: Compare files between different remote servers
- Remote Terminal: Open an SSH terminal in the project's remote folder – uses your private key and jump hosts (SFTP only)
- Transfer Queue: Monitor and manage active transfers
- Clear Error Reporting: Failed transfers show the reason, a notification with Retry, full details on click, and a persistent "X failed" indicator
- Progress Indicators: Visual feedback for all operations
- Logging: Comprehensive logging for debugging
- Git Integration: Upload only git-changed files
StackerFTP is designed to work seamlessly with Visual Studio Code and all its major forks and alternative marketplaces.
- Supported IDEs: VS Code, Cursor, Antigravity, Windsurf, VSCodium, PearAI, Trae and more.
- Marketplaces: Available on the official VS Code Marketplace and Open VSX Registry.
- Download the latest
.vsixfile from releases - Open VS Code or your IDE (Cursor, Windsurf, Antigravity, etc.)
- Go to Extensions view (Ctrl+Shift+X)
- Click "..." (More Actions) → "Install from VSIX..."
- Select the downloaded
.vsixfile
- Open VS Code or your IDE (Cursor, Windsurf, Antigravity, etc.)
- Go to Extensions view (Ctrl+Shift+X)
- Search for "StackerFTP"
- Click Install
- Open a workspace folder in your IDE
- Click StackerFTP icon in the sidebar
- Click the "+" button in the Connections header
- Fill in your connection details
- Press
Ctrl+Shift+P - Type "SFTP: Quick Connect"
- Select or create a connection
- Create
.vscode/sftp.jsonin your workspace - Edit the configuration file:
{
"name": "My Server",
"host": "example.com",
"protocol": "sftp",
"port": 22,
"username": "username",
"password": "password",
"remotePath": "/var/www/html",
"uploadOnSave": false
}- Click on a connection in the Connections panel
- Click the play button to connect
- Or right-click and select "Connect"
- Upload: Right-click a local file → "Upload to Remote"
- Download: Right-click a remote file → "Download"
- Sync: Right-click a folder → "Sync Local → Remote" or "Sync Remote → Local"
- Edit: Double-click a remote file to edit locally with auto-upload on save
When more than one connection is configured, StackerFTP asks once which server to use and remembers your choice. All transfers, Upload on Save, the file watcher and the status bar use that target connection.
- Change the target:
StackerFTP: Select Target Connection, or click the connection name in the status bar. - How long it is remembered:
stackerftp.rememberTargetConnectionsession(default) – until you disconnect from it or reload the windowworkspace– kept across reloads and restarts
- Upload on Save / File Watcher never guess: if no target is chosen yet, nothing is uploaded in the background.
Right-click files or folders (or use the editor context menu) → StackerFTP →
- Upload to Multiple Servers… – pick servers, e.g. staging + production. The selection is remembered for next time.
- Upload to All Servers – every configured connection, after a confirmation.
A per-server summary shows what was uploaded, skipped or failed.
⚠️ Beta feature – test carefully. It uploads files to your servers and can overwrite live files. Try it on a staging server first, check every line of the confirmation dialog and keep a backup of anything you cannot recreate. Please report problems in the issue tracker.
StackerFTP: Upload Commit Files... (Command Palette, or the Source Control title menu) opens a window with the files changed by the commits you pick (the latest commit is preselected; you can tick several). Nothing is uploaded until you press Upload and confirm.
Which file goes to which connection
- A file belongs to the connection whose
context(local folder) contains it. If several contexts contain it, the deepest folder wins – e.g.app_landing/dist/index.htmlgoes to the connection with"context": ".../app_landing/dist", not to the one with the project root. - The remote path is
remotePath+ the file's path relative to thatcontext. It is shown under every file and again in the confirmation dialog. - The connection's
ignorelist is applied last; ignored files are not re-routed to another connection. - Connections that share the same
contextstay switched off unless they have"uploadOnCommit": true(or are the current target) – you choose.
Safety rules
- Deleted files are never removed from the server; renames upload the new path only.
- Files matching
stackerftp.commitUploadProtected(default:config,.env*,*.server.php,*.pem,*.key,id_rsa*) are marked ⚠ and start unchecked. - Files matching
stackerftp.commitUploadUnselected(default:AGENTS.md) are listed but start unchecked, without a warning. - Switch a whole connection off, or uncheck single files, before uploading.
Optional automation (off by default): set "uploadOnCommit": true on a connection to preselect it, and enable stackerftp.commitUploadPrompt to open the window after every commit. It still only asks – it never uploads on its own.
SFTP: Sync Local → Remote, SFTP: Sync Remote → Local and SFTP: Sync Both Directions (also on folders in the Explorer) work in three steps:
- Scan both sides (ignored folders are skipped entirely).
- Preview only the changes, grouped as Upload, Download and Delete. Uncheck anything you don't want. Conflicts – e.g. the server copy is newer than yours – are shown with ⚠ and are not selected by default.
- Apply the selection through the Transfer Queue.
| Local → Remote | Remote → Local | Both | |
|---|---|---|---|
| New / changed files | uploaded | downloaded | newer side wins |
| Files missing on the source side | deleted on the server only with "syncMode": "full" |
moved to trash only with "syncMode": "full" |
never deleted |
Deletions always need an extra confirmation. .git and .vscode/sftp.json are never transferred. Turn the preview off with stackerftp.confirmSync: false to apply the recommended changes directly.
Run Compare with Remote from the Command Palette (whole project), or right-click a folder (that folder) or a file (diff). The Compare Folders panel shows local and remote side by side:
- Colors follow your theme: modified, only local, only remote (high contrast themes get a clear marker instead of tinted rows).
- Hover a file for actions: ⇆ diff, ↑ upload, ↓ download, reveal.
- Toolbar: search, filters (All / Only Local / Only Remote / Different), Export (CSV/JSON), ⇧ Sync to Remote, ⇩ Sync to Local (with preview) and ↻ Refresh.
- A progress bar at the top shows while comparing, transferring or preparing a diff.
Compare and Sync use the same ignore rules and change detection.
Turn on stackerftp.warnIfTargetNewer to avoid overwriting each other's changes: before a file is uploaded (also on save) or downloaded, StackerFTP checks whether the target is newer and asks whether to Overwrite, Compare (opens a diff) or Skip.
- The Transfer Queue shows the reason next to the file, e.g.
↑ Error: Permission denied. - After the run, a notification offers Show Details, Retry and Show Queue.
- Click a failed item for the full error, server, local and remote path – with Retry, Copy Error and Show Log.
- The status bar shows a red X failed indicator until the failures are retried or cleared.
{
"name": "My Server",
"host": "server.example.com",
"protocol": "sftp",
"port": 22,
"username": "root",
"password": "password",
"remotePath": "/var/www/html",
"uploadOnSave": true
}{
"name": "Production Server",
"host": "server.example.com",
"protocol": "sftp",
"port": 22,
"username": "root",
"privateKeyPath": "~/.ssh/id_rsa",
"passphrase": "optional-key-passphrase",
"remotePath": "/var/www/production",
"uploadOnSave": true
}{
"name": "Multi-Environment",
"username": "developer",
"password": "password",
"remotePath": "/app",
"profiles": {
"dev": {
"host": "dev.example.com",
"uploadOnSave": true
},
"staging": {
"host": "staging.example.com"
},
"production": {
"host": "prod.example.com",
"uploadOnSave": false
}
},
"defaultProfile": "dev"
}{
"name": "FTP Server",
"host": "ftp.example.com",
"protocol": "ftp",
"port": 21,
"username": "user",
"password": "pass",
"passive": true,
"remotePath": "/public_html"
}{
"name": "FTPS Server",
"host": "ftp.example.com",
"protocol": "ftps",
"port": 21,
"username": "user",
"password": "pass",
"remotePath": "/public_html"
}"protocol": "ftps" always uses TLS (explicit, port 21). For implicit TLS (usually port 990) set "secure": "implicit". For self-signed certificates on servers you trust, add "secureOptions": { "rejectUnauthorized": false }.
{
"name": "Watch Mode",
"host": "server.example.com",
"protocol": "sftp",
"username": "user",
"password": "pass",
"remotePath": "/var/www",
"watcher": {
"files": "dist/**/*",
"autoUpload": true,
"autoDelete": false
}
}{
"name": "Advanced Config",
"host": "server.example.com",
"protocol": "sftp",
"port": 22,
"username": "user",
"privateKeyPath": "~/.ssh/id_rsa",
"passphrase": "key-passphrase",
"remotePath": "/home/user/project",
"context": "src",
"uploadOnSave": true,
"downloadOnOpen": false,
"syncMode": "update",
"ignore": [
".git",
".DS_Store",
"node_modules",
"*.log"
],
"connTimeout": 10000,
"keepalive": 10000
}| Option | Type | Default | Description |
|---|---|---|---|
name |
string | - | Connection display name |
host |
string | - | Server hostname or IP |
port |
number | 22/21 | Server port |
protocol |
string | "sftp" | Protocol: "sftp", "ftp", or "ftps" |
username |
string | - | Username for authentication |
password |
string | - | Password for authentication |
privateKeyPath |
string | - | Path to SSH private key |
passphrase |
string | - | Passphrase for encrypted private key |
remotePath |
string | "/" | Remote directory path |
context |
string | workspace root | Local folder mapped to remotePath: relative to the workspace, absolute, or ~/... |
localPath |
string | - | Alias of context (vscode-sftp style); context wins if both are set |
uploadOnSave |
boolean | false | Auto-upload on file save |
downloadOnOpen |
boolean | false | Save files opened from the Remote Explorer into the project |
syncMode |
string | "update" | "update" (never deletes) or "full" (sync also deletes files missing on the source side, after confirmation) |
ignore |
array | node_modules, .vscode, … | Patterns never transferred. .git and .vscode/sftp.json are always ignored |
watcher |
object | - | File watcher configuration |
profiles |
object | - | Multiple server profiles |
defaultProfile |
string | - | Default profile to use |
hop |
object/array | - | Jump host configuration |
connTimeout |
number | 10000 | Connection timeout in ms |
keepalive |
number | 10000 | Keepalive interval in ms |
autoReconnect |
boolean | true | Reconnect when the connection drops unexpectedly |
remoteExplorerOrder |
string | "name" | Remote Explorer sort: "name", "size", "date" or "type" |
secure |
boolean / "implicit" | true for ftps | TLS mode for FTPS |
secureOptions |
object | - | TLS options, e.g. { "rejectUnauthorized": false } |
| Command | Windows/Linux | Mac |
|---|---|---|
| Upload Current File | Ctrl+Shift+U |
Cmd+Shift+U |
| Download | Ctrl+Shift+D |
Cmd+Shift+D |
| Sync to Remote | Ctrl+Shift+Alt+U |
Cmd+Shift+Alt+U |
| Sync to Local | Ctrl+Shift+Alt+D |
Cmd+Shift+Alt+D |
Open VS Code settings and search for "StackerFTP":
| Setting | Type | Default | Description |
|---|---|---|---|
stackerftp.showHiddenFiles |
boolean | false | Show hidden files in remote explorer |
stackerftp.confirmDelete |
boolean | true | Confirm before deleting remote files |
stackerftp.confirmSync |
boolean | true | Show the sync preview before applying changes |
stackerftp.rememberTargetConnection |
string | "session" | Remember the target connection for the "session" or the "workspace" |
stackerftp.rememberMultiTargets |
boolean | true | Pre-select the servers last used with "Upload to Multiple Servers" |
stackerftp.preserveTimestamps |
boolean | true | Keep modification times on transferred files |
stackerftp.warnIfTargetNewer |
boolean | false | Ask before overwriting a newer file (e.g. changed by a teammate on the server): Overwrite / Compare / Skip |
stackerftp.autoRefresh |
boolean | true | Auto refresh remote explorer after operations |
stackerftp.transferConcurrency |
number | 4 | Number of concurrent file transfers |
stackerftp.showWebMasterTools |
boolean | true | Show web master tools in context menu |
| Protocol | Port | Encryption | Authentication | Use Case |
|---|---|---|---|---|
| SFTP | 22 | SSH (Strong) | Password / SSH Key | Production servers, sensitive data |
| FTP | 21 | None | Password | Local networks, legacy systems |
| FTPS | 21 | TLS/SSL | Password / Certificate | Secure FTP without SSH |
Choose SFTP when:
- ✅ You have SSH access to the server
- ✅ Security is a priority
- ✅ Transferring sensitive data
- ✅ Working with production servers
- ✅ Need remote terminal access
Choose FTP when:
- ✅ Local development environment
- ✅ Legacy server without SSH
- ✅ Quick testing (not for production)
- ✅ Behind secure VPN/firewall
Choose FTPS when:
- ✅ FTP server with SSL/TLS support
- ✅ Need encrypted FTP without SSH
- ✅ Shared hosting environments
- ✅ Certificate-based authentication
Already configured a connection but want to change the protocol?
- Press
Ctrl+Shift+P - Type "SFTP: Switch Protocol"
- Select the connection
- Choose new protocol
Your settings (host, username, etc.) will be preserved!
- Right-click a remote file/folder
- Select "Permissions (chmod)"
- Enter the new permission (e.g., 755, 644)
- Right-click a remote file
- Select "Checksum"
- Choose algorithm (MD5, SHA1, SHA256)
- Compare with local file or copy to clipboard
- Press
Ctrl+Shift+P - Type "Search in Remote"
- Enter search pattern
- Results will show file path, line number, and content
- Right-click a remote file/folder
- Select "Backup"
- Optionally specify backup name
- Backup will be created with timestamp
- Press
Ctrl+Shift+P - Type "Purge Remote Cache"
- Common cache directories will be cleared
- Check your firewall settings
- Verify server address and credentials
- For SFTP: Ensure SSH is enabled on the server
- For FTPS: Check if server requires explicit or implicit TLS
- Check file permissions on remote server
- Verify disk space on remote server
- Check transfer logs:
Ctrl+Shift+P→ "SFTP: View Logs"
- Reduce transfer concurrency in settings
- Use passive mode for FTP behind NAT
- Enable compression for SFTP connections
We welcome contributions! Please see our Contributing Guide for details.
MIT License - see LICENSE file for details.
StackerFTP is inspired by the excellent vscode-sftp extension by Natizyskunk, which was originally forked from liximomo's SFTP plugin.
- GitHub Issues: github.com/yasinkuyu/stackerftp/issues
Enjoy using StackerFTP! 🚀