Features

Promise-Based API

Modern, clean API with full Promise support for all SSH operations. No callback hell!

Flexible Authentication

Support for private keys (path/buffer), password, and keyboard interactive authentication methods.

File Operations

Robust file transfer capabilities including single file transfers and recursive directory operations.

Command Execution

Execute remote commands with full control over stdin/stdout and support for PTY options.

Getting Started

Installation

Choose your preferred package manager:

npm

$ npm install node-ssh

yarn

$ yarn add node-ssh

pnpm

$ pnpm add node-ssh

Basic Usage

const { NodeSSH } = require('node-ssh')
const ssh = new NodeSSH()

ssh.connect({
  host: 'localhost',
  username: 'steel',
  privateKey: '/home/steel/.ssh/id_rsa'
})
.then(async () => {
  // Ready for commands
  const result = await ssh.execCommand('echo $PATH')
})

Ready to explore more? Check out our complete API documentation for detailed information about all available methods and options.

View Complete API ReferenceExternal link icon

Examples

File Transfer

// Upload a file
await ssh.putFile('/local/path/file.txt', '/remote/path/file.txt')

// Download a file
await ssh.getFile('/remote/path/file.txt', '/local/path/file.txt')

// Upload a directory
await ssh.putDirectory('/local/path', '/remote/path', {
  recursive: true,
  concurrency: 10,
  validate: (itemPath) => {
    const baseName = path.basename(itemPath)
    return baseName.substr(0, 1) !== '.' // skip hidden files
  }
})

Command Execution

// Simple command execution
const result = await ssh.execCommand('ls -la')
console.log('STDOUT:', result.stdout)
console.log('STDERR:', result.stderr)

// With working directory and stream handlers
const result = await ssh.exec('git', ['pull'], {
  cwd: '/var/www/app',
  onStdout: (chunk) => {
    console.log('Output:', chunk.toString('utf8'))
  },
  onStderr: (chunk) => {
    console.log('Error:', chunk.toString('utf8'))
  }
})

Keyboard Interactive Authentication

ssh.connect({
  host: 'localhost',
  username: 'steel',
  port: 22,
  password: 'mypassword',
  tryKeyboard: true,
  onKeyboardInteractive(name, instructions, lang, prompts, finish) {
    if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) {
      finish(['mypassword'])
    }
  }
})

TypeScript Support

Install the required type definitions:

$ npm install --save-dev @types/ssh2

Add these compiler options to your tsconfig.json if needed:

{
  "compilerOptions": {
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  }
}