Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>FTP/SFTP Explorer (NppFTP style)New to Visual Studio Code? Get it now.
FTP/SFTP Explorer (NppFTP style)

FTP/SFTP Explorer (NppFTP style)

Sanater

|
5 installs
| (0) | Free
NppFTP-style FTP, FTPS, FTPES and SFTP client with an SSH terminal: profile manager, remote file tree, open-edit-save-autoupload, permissions, message window and matching tag highlighting.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

FTP/SFTP Explorer — an NppFTP-style VS Code extension

English · Türkçe sürüm: README.tr.md

Developer: Sanater

An FTP client that brings the workflow of NppFTP (the Notepad++ plugin) to VS Code: define a profile → connect → click a file in the remote tree → edit → save, and it uploads itself.

No NppFTP code was used — only its behaviour and dialog layout were taken as a reference. This extension is written from scratch in TypeScript.


Features

NppFTP This extension
Profile settings dialog FTP Profiles webview (Add / Duplicate / Delete)
FTP, FTPES, FTPS, SFTP Same (basic-ftp + ssh2-sftp-client)
Remote file tree FTP view in the activity bar
Double-click to open, save to upload Same; the mapping is stored persistently
Download / Upload / Upload as Download, Download To, Upload Files/Folder Here
New file / New dir / Rename / Delete Same (folder deletion is recursive)
Permissions (chmod) Permissions (SETSTAT over SFTP, SITE CHMOD over FTP)
Properties Properties (size, date, permissions, owner)
Message window FTP output channel (raw protocol at trace level)
Cache (local↔remote mapping) Per-profile local root or the extension cache

On top of that:

  • SSH terminal — opens a shell on the same server (not in NppFTP).
  • Matching tag highlighting — Notepad++'s own feature, brought along too.
  • Drag & drop: drop local files onto the tree to upload, drag inside the tree to move.
  • Passwords and SSH key passphrases go to the operating system credential store (VS Code SecretStorage), never into the profile file.
  • Silent reconnect when the connection drops while saving.
  • Status bar indicator, keep-alive, timeout, ASCII/binary transfer mode.
  • English and Turkish user interface.

Installation

From the Marketplace: open the Extensions panel (Ctrl+Shift+X), search for FTP/SFTP Explorer and click Install.

From a .vsix file: Extensions panel → ... menu → Install from VSIX..., or from a terminal:

code --install-extension ftp-explorer-<version>.vsix

Reload the window afterwards (Ctrl+Shift+P → Developer: Reload Window). The FTP icon appears in the activity bar.

To build from source see Development below.


Language

The extension speaks English and Turkish. By default it follows the VS Code display language; to pin one explicitly:

"ftpx.language": "en"    // "auto" (default) | "en" | "tr"

This setting covers messages, dialogs, the profile window and the message window. Command and menu titles are translated through the VS Code platform mechanism instead, so those follow the display language (Ctrl+Shift+P → Configure Display Language) and require the matching language pack.


Getting started

  1. Click the FTP icon in the activity bar.
  2. Open Profile Settings, press Add and fill in the protocol, host, username and password. Then Save and Connect.
  3. Click a file in the remote tree — it is downloaded to a local cache and opened in the editor.
  4. Edit and press Ctrl+S — the file is uploaded back automatically.

To upload the current file manually: Ctrl+Alt+U (FTP: Upload Current File).

Profile fields

Field Meaning
Protocol FTP, FTPES (21 / AUTH TLS), FTPS (990 / implicit TLS), SFTP (22)
Method (SFTP) Password, private key (~/.ssh/id_ed25519) or SSH agent
Initial remote directory Root of the tree. Leave / to use the server working directory
Local root directory Empty = extension cache. If set, the remote tree is mirrored into that folder
Transfer mode Binary, ASCII, or Automatic by file extension
Excluded patterns Names hidden in the tree, e.g. *.tmp, .git, node_modules

SSH terminal

You do not need a separate program to run php artisan cache:clear after uploading a file. An interactive shell opens on the same server, inside the VS Code terminal panel — no PuTTY or OpenSSH installation required.

How to open Where
The terminal icon in the FTP view title While connected
Right-click a folder in the tree → Open SSH Terminal Here The shell starts in that directory
Command palette → FTP: Open SSH Terminal Lets you pick a profile even when disconnected

Credentials come from the same place as the FTP/SFTP connection, and are not asked for again if the profile is already connected. Servers requiring keyboard-interactive authentication are supported. Terminal resizes are forwarded to the server, so full-screen programs such as top, htop and nano work correctly. Multi-byte UTF-8 characters survive chunk boundaries.

Which profiles can use it?

  • SFTP profiles automatically — same host, port and credentials.
  • FTP / FTPS / FTPES profiles once you enable the SSH terminal section in the profile settings. Port (22 by default) and username can be overridden; the FTP password is reused. If you need key-based authentication, create a separate profile using the SFTP protocol.

Matching tag highlighting

Move the cursor into a tag and both the opening and the closing tag stand out:

<div class="row">          ← highlighted as well while the cursor is in the </div> below
    <div class="col-12">
        @if($section->body)     ← @if / @endif pairs are matched too
            {!! $section->body !!}
        @endif
    </div>
</div>                     ← cursor here

Three highlight layers

Notepad++'s look is made of three separate layers; each can be toggled individually:

Layer Setting Colour What it does
Line band highlightLine ftpxTag.matchLineBackground Fills the whole line of the opening and closing tag. This is the Notepad++ "eol filled" style and the layer that makes start and end obvious at a glance.
Tag scope ftpxTag.matchBackground <div … > and </div>
Attribute names highlightAttributes ftpxTag.attributeBackground Only the class, id, style … names of the matching tag. Values are not coloured.

How much gets coloured? (ftpx.tagHighlight.scope)

In the default tag mode attribute values are not painted. This matters for Tailwind projects where a single tag can exceed 300 characters:

<!-- scope: "tag" (default) -->   <div class="..." style="...">  →  <div  and  >
<!-- scope: "name" -->            just  div
<!-- scope: "full" -->            the whole tag (Notepad++'s "highlight tag attributes" look)

Measured on a real 212-line Tailwind Blade file: full painted 76 characters per tag on average and 356 in the worst case; tag paints 11 on average, 19 at worst.

What the scanner handles

  • < inside <!-- --> comments, <script> / <style> / <textarea> content and <?php ... ?> blocks is not treated as a tag.
  • A quoted > such as <a title="a > b"> does not end the tag.
  • In-tag Blade expressions like <div {{ $attrs }} class="{!! $c !!}"> are skipped.
  • Void elements (<br>, <img>, <input>) and <x /> are not openings.
  • Unclosed <li> / <p> tags do not break the enclosing pair.
  • Blade component tags such as <x-layout.app> and <x-slot:head> are supported.
  • Attribute scanning keeps Vue/Alpine forms: :class, @click, @click.prevent, x-on:click.prevent, v-if, #slot.

Blade block directives are matched as well (ftpx.tagHighlight.highlightBladeDirectives): @if, @unless, @isset, @for, @foreach, @forelse, @while, @switch, @section, @push, @prepend, @once, @verbatim, @php, @auth, @guest, @can, @cannot, @canany, @error, @production, @env, @component, @slot, @fragment, @session and @hasSection. Single-line forms (@section('title', 'Page'), @php($x = 1)) do not open a block; @@if escapes and text like user@if.com are not directives.

Commands

Command Shortcut
Tag Matching: Go to Matching Tag Ctrl+Alt+M
Tag Matching: Select Tag Block —

Changing the colours

In settings.json:

"workbench.colorCustomizations": {
  "ftpxTag.matchBackground": "#a074c470",
  "ftpxTag.matchLineBackground": "#8a6fc42e",
  "ftpxTag.attributeBackground": "#d9b23a4d",
  "ftpxTag.matchBorder": "#c08cf0cc",
  "ftpxTag.guideForeground": "#a074c470"
}

Settings

Setting Default Description
ftpx.language auto Extension language: auto / en / tr
ftpx.onSave upload On save: upload / ask / none
ftpx.confirmDelete true Ask before deleting
ftpx.showHiddenFiles true Show dot files
ftpx.sortFoldersFirst true Sort folders first
ftpx.logLevel info off / info / debug / trace
ftpx.cachePath "" Folder for downloaded files
ftpx.autoConnectProfile "" Profile to connect to on startup
ftpx.reconnectOnUpload true Silently re-establish a dropped connection
ftpx.tagHighlight.enabled true Matching tag highlighting
ftpx.tagHighlight.style background background / outline / underline / background+outline
ftpx.tagHighlight.bold false Render matching tags bold
ftpx.tagHighlight.scope tag tag (boundaries), name (name only), full (with attributes)
ftpx.tagHighlight.highlightLine true Fill the whole line of the matching tags
ftpx.tagHighlight.highlightAttributes true Mark attribute names of the matching tag
ftpx.tagHighlight.matchInsideContent false Match from the content between the tags too
ftpx.tagHighlight.highlightBladeDirectives true Also match @if/@endif style Blade blocks
ftpx.tagHighlight.showVerticalGuide false Draw a vertical guide between the tags
ftpx.tagHighlight.languages HTML/Blade/Vue... Enabled language ids (* = all)
ftpx.tagHighlight.maxFileSize 2000000 Skip tag matching above this size

Project layout

src/
  extension.ts        Entry point: view, status bar, save-and-upload hook
  session.ts          The single active connection + operation queue
  profileStore.ts     profiles.json + SecretStorage
  profileEditor.ts    The "FTP Profiles" webview
  tree.ts             Remote file tree + drag & drop
  commands.ts         All commands
  transfer.ts         Download/upload, progress, ASCII conversion
  cache.ts            Local↔remote mapping
  i18n.ts             Language resolution (setting + display language)
  i18n/
    core.ts           Active language, placeholder formatting, t()
    en.ts / tr.ts     Message bundles (key parity enforced by tests)
  clients/
    client.ts         Shared interface
    ftpClient.ts      FTP / FTPES / FTPS  (basic-ftp)
    sftpClient.ts     SFTP                (ssh2-sftp-client)
  ssh/
    shell.ts          SSH shell (vscode-free, testable)
    terminal.ts       Binds the shell to the VS Code terminal panel
  tagmatch/
    tags.ts           HTML/XML tag scanner + stack-based matcher
    directives.ts     Blade block directives
    match.ts          Combines both, finds the pair under the cursor
    highlighter.ts    Decorations, listeners, cache
media/                Webview HTML/CSS/JS, icons
test/                 Smoke tests against a real SFTP + SSH server
package.nls.json      Command/setting titles (English)
package.nls.tr.json   Command/setting titles (Turkish)

Development

npm install
npm run compile

Open this folder in VS Code and press F5: a separate "Extension Development Host" window starts so you can try your changes without touching the installed version.

See PUBLISHING.md in the repository for packaging and publishing.

Tests

npm test

test/sftp-server.js starts a real in-process SFTP + SSH server; test/smoke.js verifies connecting, listing, stat, downloading (including progress reporting), uploading, mkdir, rename, chmod and recursive deletion end to end. On the SSH side it covers opening a shell, running commands, multi-byte character integrity, window-size propagation, the initial directory (including quote escaping) and the wrong-password path. It also covers every corner case of the tag/directive scanner (comments, <script>, quoted >, void elements, @section forms, @@ escapes) and the consistency of the translation bundles (key parity, empty strings, placeholder agreement).


Known limitations

  • Active (PORT) FTP mode is not supported. basic-ftp only uses passive mode (PASV/EPSV); if a profile selects active mode a warning is logged and passive mode is used.
  • SSH host keys are not verified. The server key fingerprint is logged at debug level but is not compared against known_hosts.
  • ASCII mode does not rely on the server's TYPE A behaviour; line endings are converted locally instead (to the OS convention on download, to LF on upload). Binary content is detected and left untouched.
  • Only one connection at a time (same as NppFTP).
  • FTP has no single-file stat command, so "Properties" reads from the parent directory listing; some servers do not report permissions or ownership.

License and contact

MIT licensed. Developer: Sanater

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft