Skip to content

Choosing the protocol ​

Short answer: you usually do not have to. The default, protocol: 'auto', asks the server for SFTP and falls back to SCP when it has none. client.protocol tells you which one it got.

protocol: 'auto' usesSFTP
client.fsavailable
Directory copiesfiles in parallel

The common case. Nothing to configure.

ts
await connect({ host: 'example.com', username: 'deploy', privateKey });

How 'auto' decides ​

The SFTP probe costs one round trip right after login. SCP is only tried when you transfer, since it runs the scp program on the server for each operation.

What you get with each ​

SFTPSCP
upload(), download()yesyes
writeFile(), readFile()yesyes (streams without size are buffered)
client.fs (list, stat, mkdir, rm, rename)yesno, undefined
Parallel files in directory copiesyes, concurrencyno, one at a time
total in download progressyesno
Works on Dropbear, OpenWrt, network gearonly if an SFTP server is installedyes
Works on SFTP only hosts (ForceCommand internal-sftp)yesno

Errors use the same codes on both, so ERR_NOT_FOUND means "not found" whichever protocol ran.

Force one ​

ts
// Needs client.fs or many parallel files: fail early if SFTP is missing.
await connect({ ...options, protocol: 'sftp' });

// A device you know has no SFTP: skip the probe.
await connect({ ...options, protocol: 'scp' });

When scp is not on the remote PATH, point to it with scpCommand: '/usr/bin/scp'.

Want the background? ​

SCP or SFTP in 2026? explains how the two protocols work, what OpenSSH 9 changed and where each one still wins.

Released under the MIT License.