Export files to SFTP in Node.js with ssh2-sftp-client
Secure file transfers are crucial for protecting sensitive data. SFTP (Secure File Transfer
Protocol) is a reliable method for securely transferring files over a network. In this DevTip, we'll
explore how to use Node.js and the open-source library ssh2-sftp-client to efficiently handle file
transfers to and from an SFTP server. ssh2-sftp-client is a convenient, promise-based wrapper
around the powerful ssh2 library, simplifying SFTP operations.
Introduction to SFTP
SFTP is a secure protocol built on SSH (Secure Shell) that provides encrypted file transfers. It ensures data integrity and confidentiality, making it ideal for transferring sensitive information.
Setting up your Node.js environment
This example uses ssh2-sftp-client 12.x with Node.js 22 or newer. You can verify your installation
by running:
node -v
npm -v
Installing and configuring ssh2-sftp-client
Install the ssh2-sftp-client library using npm:
npm install ssh2-sftp-client@12
Connecting, uploading, downloading, and error handling
Here's how you can establish a connection, upload a file, download a file, and handle errors
robustly. Set SFTP_HOST, SFTP_USERNAME, SFTP_PASSWORD, and SFTP_HOST_SHA256 through your
environment. Obtain the server's host-key fingerprint from its administrator over a trusted
channel. SFTP_HOST_SHA256 must be the lowercase 64-character SHA-256 hex digest of the raw SSH
public-key bytes, not the SHA256: base64 form shown by many SSH tools. Do not learn this value
from an unverified first connection.
const Client = require('ssh2-sftp-client')
const fs = require('fs') // Required for the dummy file creation
async function main() {
const { SFTP_HOST, SFTP_USERNAME, SFTP_PASSWORD, SFTP_HOST_SHA256 } = process.env
if (!SFTP_HOST || !SFTP_USERNAME || !SFTP_PASSWORD || !/^[a-f0-9]{64}$/.test(SFTP_HOST_SHA256 || '')) {
throw new Error('SFTP credentials and a verified SHA-256 host-key fingerprint are required')
}
const sftp = new Client()
const config = {
host: SFTP_HOST,
port: 22, // Use an integer for the port
username: SFTP_USERNAME,
password: SFTP_PASSWORD,
hostHash: 'sha256',
hostVerifier: (fingerprint) => fingerprint === SFTP_HOST_SHA256,
readyTimeout: 10000,
}
const localPath = './local-file.txt'
const remotePath = '/remote/path/file.txt'
const localDownloadPath = './downloaded-file.txt'
// Create a dummy file for upload example if it doesn't exist
if (!fs.existsSync(localPath)) {
fs.writeFileSync(localPath, 'This is a test file for SFTP upload.')
console.log(`Created dummy ${localPath} for testing.`)
}
try {
await sftp.connect(config)
console.log('Connected successfully to SFTP server.')
// Uploading files
console.log(`Attempting to upload ${localPath} to ${remotePath}...`)
await sftp.put(localPath, remotePath)
console.log('File uploaded successfully.')
// Downloading files
console.log(`Attempting to download ${remotePath} to ${localDownloadPath}...`)
await sftp.get(remotePath, localDownloadPath)
console.log('File downloaded successfully.')
} finally {
await sftp.end()
}
}
main().catch(() => {
console.error('SFTP transfer failed; check configuration, host identity, and permissions')
process.exitCode = 1
})
In the example above, we've wrapped our SFTP operations within an async function called main.
This function handles connecting to the server, uploading a file, and then downloading it. The
try...finally block ensures that the SFTP connection is closed using sftp.end() regardless of
whether the operations were successful or an error occurred. We also create a dummy local-file.txt
to ensure the upload example can run. Choose remote and local download paths that are safe to
replace; these transfer methods can overwrite existing files. Transfer failures produce a nonzero
exit status, so a scheduled job does not incorrectly report success.
The underlying ssh2 client accepts host keys by
default if no verifier is supplied. Encryption alone is not server authentication; the explicit
fingerprint check is essential for detecting an unexpected server key.
Best practices for secure and efficient file transfers
- Always use strong authentication methods. For enhanced security, using SSH key-based
authentication is highly recommended. The
privateKeyoption in theconnectconfig can be used for this. Refer to thessh2-sftp-clientandssh2documentation for detailed examples. - Regularly update your libraries and dependencies.
- Validate file paths and permissions.
- Implement logging and monitoring for file transfers.
Conclusion and practical use cases
Using ssh2-sftp-client simplifies secure file transfers in Node.js applications. This approach is
ideal for automated backups, data synchronization, and secure file exchanges between systems.
For a streamlined solution, consider Transloadit's 🤖 /sftp/store Robot as part of our File Exporting service.
