How to connect to SFTP in Node.js: Upload, Download, List Files
Need to connect to an SFTP server using Node.js? This guide shows how to connect to SFTP in Node.js using ssh2-sftp-client, then list files, upload, download, delete files, and close the session cleanly.
We’ll use ssh2-sftp-client, a common Node.js SFTP library built on ssh2, so the code stays readable while still covering the operations you actually use in automation.
Connection details come from one environment variable, SFTPTOGO_URL, formatted as sftp://user:password@host, so you can run the same method locally, in CI, or on a server without hardcoding secrets.
What this guide covers:
- How to connect to an SFTP server in Node.js
- How to list, upload, and download files over SFTP
- How to handle authentication and connection details
- Common Node.js SFTP errors and how to fix them
Node.js SFTP setup requirements
First things first: preparation. ssh2-sftp-client is a Node.js SFTP client library that wraps ssh2 and gives you a clean API for common file operations like list(), put(), and get().
This guide uses ssh2-sftp-client@^8.0.0 because the code examples below were written and tested against that version. If you are using a newer ssh2-sftp-client release in your own project, check its Node.js version requirements and test the code before using it in production.
npm install ssh2-sftp-client@^8.0.0
Or add a package.json file and declare your dependencies in it:
{
"dependencies": {
"ssh2-sftp-client": "^8.0.0"
}
}
Then, run the following:
npm install
Connect to an SFTP server in Node.js
As an example for this post, we’ll use an environment variable named SFTPTOGO_URL, which contains everything required to connect to an SFTP server in a URI format: sftp://user:password@host. In the example below, Node’s built-in URL parser extracts the connection parts (host, username, password, and port) before opening the session.
let Client = require('ssh2-sftp-client');
class SFTPClient {
constructor() {
this.client = new Client();
}
async connect(options) {
console.log(`Connecting to ${options.host}:${options.port}`);
try {
await this.client.connect(options);
} catch (err) {
console.log('Failed to connect:', err);
}
}
async disconnect() {
await this.client.end();
}
}connect.js
List files over SFTP in Node.js
Once a working connection has been established, you may use it to list files on the remote SFTP server. This can be done by calling the ssh2-sftp-client’s list method and iterating over the returned array, which then corresponds to the files found in the path argument. In our example, our wrapper function simply prints out the files found in the remote path.
This is the basic pattern most Node.js SFTP scripts follow: connect, list() files, then decide what to download or process next.
async listFiles(remoteDir, fileGlob) {
console.log(`Listing ${remoteDir} ...`);
let fileObjects;
try {
fileObjects = await this.client.list(remoteDir, fileGlob);
} catch (err) {
console.log('Listing failed:', err);
}
const fileNames = [];
for (const file of fileObjects) {
if (file.type === 'd') {
console.log(`${new Date(file.modifyTime).toISOString()} PRE ${file.name}`);
} else {
console.log(`${new Date(file.modifyTime).toISOString()} ${file.size} ${file.name}`);
}
fileNames.push(file.name);
}
return fileNames;
}
listfiles.js
Upload Files over SFTP in Node.js
The next step is to upload a file. Use the client object’s put function and pass the path to the local file and the remote path ( the file should also end up here after the upload). A function call would look like this: await client.uploadFile("./local.txt", "./remote.txt");
Upload is usually the first step in automated SFTP workflows, so keep paths explicit and log failures clearly.
async uploadFile(localFile, remoteFile) {
console.log(`Uploading ${localFile} to ${remoteFile} ...`);
try {
await this.client.put(localFile, remoteFile);
} catch (err) {
console.error('Uploading failed:', err);
}
}
uploadfile.js
Download Files over SFTP in Node.js
To finalize the process, you just need to download the files. Use the client object get function and pass the path to the remote file and the local path in which to store the downloaded file. You would call the function like so: await client.downloadFile("./remote.txt", "./download.txt");
Download is where scripts often fail in the real world, so keep local paths explicit and always close the session afterward.
async downloadFile(remoteFile, localFile) {
console.log(`Downloading ${remoteFile} to ${localFile} ...`);
try {
await this.client.get(remoteFile, localFile);
} catch (err) {
console.error('Downloading failed:', err);
}
}
downloadfile.js
Troubleshooting Node.js SFTP connections
If something fails, it’s usually one of these. These checks are quick, and they map well to SFTP To Go setups.
- Confirm the credential: Copy the exact
Host,Username, AndPasswordfrom your SFTP To Go dashboard credential, then updateSFTPTOGO_URLif anything changed. - Check port 22 access: Make sure your environment can reach the SFTP host on port
22. If you are running from CI or a locked-down network, outbound22is a common block. - Fix authentication issues: If you see
Authentication failed, it is usually a wrong username or password, or special characters breaking the URL. If the password includes@,:, Or/, URL-encode it before placing it intoSFTPTOGO_URL. - Sanity-check remote paths: If you get
Permission deniedor “no such file”, start by listing.and work from the user’s home directory. Then use explicit remote paths. - Use audit logs to confirm what happened: If you are unsure whether the server received the login or file action, check SFTP To Go audit logs for logins and file activity.
- Check platform status if everything suddenly fails: If you have failures across multiple environments at the same time, check
https://status.crazyantlabs.com/before changing working code.
The whole Node.js SFTP example script
After following the above steps, the process is complete! Lastly, if you would like to run the entire program from start to finish, copy the following code and save it as main.js.
sftp.js, but in this guide the script is saved and run as main.js.// sftp.js
//
// Use this sample code to connect to your SFTP To Go server and run some file operations using Node.js.
//
// 1) Paste this code into a new file (sftp.js)
//
// 2) Install dependencies
// npm install ssh2-sftp-client@^8.0.0
//
// 3) Run the script
// node sftp.js
//
// Compatible with Node.js >= v12
// Using ssh2-sftp-client v8.0.0
let Client = require('ssh2-sftp-client');
class SFTPClient {
constructor() {
this.client = new Client();
}
async connect(options) {
console.log(`Connecting to ${options.host}:${options.port}`);
try {
await this.client.connect(options);
} catch (err) {
console.log('Failed to connect:', err);
}
}
async disconnect() {
await this.client.end();
}
async listFiles(remoteDir, fileGlob) {
console.log(`Listing ${remoteDir} ...`);
let fileObjects;
try {
fileObjects = await this.client.list(remoteDir, fileGlob);
} catch (err) {
console.log('Listing failed:', err);
}
const fileNames = [];
for (const file of fileObjects) {
if (file.type === 'd') {
console.log(`${new Date(file.modifyTime).toISOString()} PRE ${file.name}`);
} else {
console.log(`${new Date(file.modifyTime).toISOString()} ${file.size} ${file.name}`);
}
fileNames.push(file.name);
}
return fileNames;
}
async uploadFile(localFile, remoteFile) {
console.log(`Uploading ${localFile} to ${remoteFile} ...`);
try {
await this.client.put(localFile, remoteFile);
} catch (err) {
console.error('Uploading failed:', err);
}
}
async downloadFile(remoteFile, localFile) {
console.log(`Downloading ${remoteFile} to ${localFile} ...`);
try {
await this.client.get(remoteFile, localFile);
} catch (err) {
console.error('Downloading failed:', err);
}
}
async deleteFile(remoteFile) {
console.log(`Deleting ${remoteFile}`);
try {
await this.client.delete(remoteFile);
} catch (err) {
console.error('Deleting failed:', err);
}
}
}
(async () => {
const parsedURL = new URL(process.env.SFTPTOGO_URL);
const port = parsedURL.port || 22;
const { host, username, password } = parsedURL;
//* Open the connection
const client = new SFTPClient();
await client.connect({ host, port, username, password });
//* List working directory files
await client.listFiles(".");
//* Upload local file to remote file
await client.uploadFile("./local.txt", "./remote.txt");
//* Download remote file to local file
await client.downloadFile("./remote.txt", "./download.txt");
//* Delete remote file
await client.deleteFile("./remote.txt");
//* Close the connection
await client.disconnect();
})();
main.js
Finally, run it using the command:
node main.jsIn conclusion
Congratulations on connecting to SFTP using Node.js!
You now have a complete Node.js SFTP workflow: connect to an SFTP server, list files, upload, download, delete, and close the session cleanly.
For production use, add host key verification, timeouts, and structured error handling so your SFTP automation is reliable and secure. From here, you can extend this into scheduled jobs, CI pipelines, or automated file processing workflows.
Check out more code samples on Github. Explore SFTP automation to reduce human error and streamline workflows.
Frequently asked questions
How do I connect to an SFTP server in Node.js?Use a Node.js SFTP client library like ssh2-sftp-client, pass host, port, and credentials, then open the session before running file operations like list(), upload, and download.
ssh2-sftp-client is a Node.js SFTP client library that wraps ssh2 and provides a higher-level API for common SFTP operations like connect, list(), put(), and get().
SFTPTOGO_URL is an environment variable containing a connection URI such as sftp://user:password@host. The example script parses it to extract host, username, password, and port.
SFTP usually runs on port 22 because it uses SSH. If your server uses a different port, set it in the URL or pass it explicitly in the connection options.
Most timeouts come from network path issues: wrong host or port, blocked outbound traffic, missing server-side allowlist entries, or the server not accepting SSH connections from your source IP.
Does ssh2-sftp-client verify the SFTP server host key?You should not assume strict host key verification unless you explicitly configure it. For production, verify or pin the SSH host key fingerprint so you can detect unexpected host key changes.