Remote file system operations/file transfer over SSH2 session without SFTP
- File operations via SSH2 shell/command session (no SFTP required)
- Supports all common file system operations
- Non-UTF-8 encoding support (e.g. GBK) via optional iconv-lite
- Both ESM and CJS exports
- TypeScript support
npm install ssh2-scpimport { Client } from 'ssh2'
import { createSshFs } from 'ssh2-scp'
const client = new Client()
client.on('ready', () => {
const fs = createSshFs(client)
// List directory
const files = await fs.list('/path/to/dir')
// Read file
const content = await fs.readFile('/path/to/file.txt')
// Write file
await fs.writeFile('/path/to/file.txt', 'Hello World')
// Get file stats
const stat = await fs.stat('/path/to/file')
console.log(stat.isFile(), stat.isDirectory(), stat.size)
// ... and more
})createSshFs(client, options?)client- An authenticated ssh2 Client instanceoptions- Optional configuration object:iconv- An iconv-lite instance for non-UTF-8 encoding support (must exposedecode(buf, encoding))encoding- Target encoding name (default:'utf-8'). Only effective wheniconvis provided
By default, ssh2-scp assumes the remote server uses UTF-8 encoding. If your server uses a different encoding (e.g. GBK on Chinese Windows systems), pass an iconv-lite instance to decode file names and command output correctly.
Install iconv-lite in your project:
npm install iconv-liteimport iconv from 'iconv-lite'
import { createSshFs } from 'ssh2-scp'
// Create an SshFs instance with GBK encoding support
const fs = createSshFs(client, { iconv, encoding: 'gbk' })
// File names are now decoded from GBK to Unicode
const files = await fs.list('/path/to/dir')
console.log(files[0].name) // '测试文件.txt' instead of garbled bytesNote:
iconv-liteis not bundled as a runtime dependency to keep the package lightweight. You only need to install it if you require non-UTF-8 encoding support.
readFile(remotePath)- Read file content as stringwriteFile(remotePath, content, mode?)- Write string content to filereadFileBase64(remotePath)- Read file as base64 encoded stringwriteFileBase64(remotePath, base64Content)- Write base64 content to file
list(remotePath)- List directory contentsmkdir(remotePath, options?)- Create directoryrmdir(remotePath)- Remove directory
cp(from, to)- Copy file or directorymv(from, to)- Move/rename file or directoryrename(oldPath, newPath)- Rename file or directoryrm(remotePath)- Remove filetouch(remotePath)- Create empty file or update timestamp
stat(remotePath)- Get file stats (follows symlinks)lstat(remotePath)- Get file stats (does not follow symlinks)realpath(remotePath)- Get canonical pathreadlink(remotePath)- Read symlink targetgetFolderSize(folderPath)- Get folder size and file count
chmod(remotePath, mode)- Change file permissions
getHomeDir()- Get home directoryrunExec(command)- Execute raw shell command
Transfer is for single-file uploads and downloads.
import { Transfer } from 'ssh2-scp/transfer'
const transfer = new Transfer(fs, {
type: 'download', // or 'upload'
remotePath: '/remote/path',
localPath: '/local/path',
chunkSize: 32768,
onProgress: (transferred, total) => {
console.log(`Progress: ${transferred}/${total}`)
}
})
await transfer.startTransfer()type- Transfer type:'download'or'upload'remotePath- Remote file pathlocalPath- Local file pathchunkSize- Chunk size for transfer (default: 32768)onProgress- Progress callback(transferred, total) => voidonData- Data callback(count) => void
FolderTransfer streams a tar archive over the SSH command channel. It is initialized from a raw ssh2 Client, supports pause/resume, and targets both POSIX servers and Windows OpenSSH servers that provide tar.
Install a tar adapter explicitly if you want folder transfer support:
npm install tarimport { Client } from 'ssh2'
import * as tar from 'tar'
import { FolderTransfer } from 'ssh2-scp/folder-transfer'
const client = new Client()
const transfer = new FolderTransfer(client, tar, {
type: 'upload',
localPath: '/local/folder',
remotePath: '/remote/folder',
chunkSize: 32768,
onProgress: (transferred, total) => {
console.log(`Progress: ${transferred}/${total}`)
}
})
await transfer.startTransfer()When transferring folders to/from servers with non-UTF-8 filenames (e.g. GBK), pass iconv and encoding options. The filenames in the tar stream are converted in real-time using a streaming tar header transform — no remote-side tools required.
import iconv from 'iconv-lite'
const transfer = new FolderTransfer(client, tar, {
type: 'download',
remotePath: '/remote/folder',
localPath: '/local/folder',
iconv,
encoding: 'gbk'
})
await transfer.startTransfer()
// Local files now have correct UTF-8 names- Constructor:
new FolderTransfer(client, tarAdapter, options) type- Transfer type:'download'or'upload'remotePath- Remote folder pathlocalPath- Local folder pathchunkSize- Stream high water mark used by the tar pipelineiconv- An iconv-lite instance for encoding conversion (must exposeencode(str, enc)anddecode(buf, enc))encoding- Remote filesystem encoding (e.g.'gbk'). Filenames in the tar stream are converted between this encoding and UTF-8tarAdapter- A tar-compatible object that exposesc()andx();tarworks out of the boxpause()/resume()- Pause or continue the active streamdestroy()- Abort the current folder transfer- Windows remotes use PowerShell plus
tar; Linux and other POSIX remotes usetardirectly
MIT