Skip to content

Getting started

This guide walks you from npm install to your first successful upload in under five minutes.

  • Node.js ≥ 20 (the SDK uses native fetch, AbortSignal.timeout, and modern stream APIs).
  • A package manager (npm, pnpm, or yarn).
  • Credentials for at least one remote system you want to talk to (SFTP server, S3 bucket, etc.).

The umbrella package brings every built-in provider:

Terminal window
npm install @zero-transfer/sdk

If you only need one or two providers, use the scoped packages instead - they pull in just that provider’s transitive deps:

Terminal window
npm install @zero-transfer/sftp
npm install @zero-transfer/s3
npm install @zero-transfer/ftps

The scoped packages re-export the same createTransferClient, uploadFile, etc. as the umbrella package, so you can swap between them without code changes.

Every operation that touches a remote system takes a ConnectionProfile. The shape is provider-neutral - you describe the destination once and reuse it.

import type { ConnectionProfile } from "@zero-transfer/sdk";
const sftp: ConnectionProfile = {
host: "sftp.example.com",
provider: "sftp",
username: "deploy",
ssh: {
privateKey: { path: "./keys/id_ed25519" },
// Pin the server's host key - without this the SSH session
// accepts any key the server presents (MITM risk).
pinnedHostKeySha256: "SHA256:abc123basesixfourpinFromKnownHosts=",
},
};

For the full field reference and every secret-loading variant, see Connection profiles.

import { createTransferClient } from "@zero-transfer/sdk";
const client = createTransferClient();
const session = await client.connect(sftp);
// `session.fs` is the unified filesystem facade. Same shape on every provider.
const releases = await session.fs.list("/releases");
console.log(releases.map((entry) => entry.name));
await session.disconnect();
import { uploadFile } from "@zero-transfer/sdk";
await uploadFile({
client,
localPath: "./dist/app.tar.gz",
destination: { path: "/releases/2026.04.28/app.tar.gz", profile: sftp },
onProgress: (event) => console.log(`${event.bytesTransferred}/${event.totalBytes ?? "?"} bytes`),
});

uploadFile reuses any pooled connection bound to that profile, so you don’t pay the connect cost twice.