New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

x-rsync

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

x-rsync

A tiny rsync-style tool using SFTP + SHA-256 diffing. Push only changed files to remote servers.

latest
Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

x-rsync

A tiny rsync-style tool built for Node/TypeScript using SFTP + SHA-256 diffing.

It lets you sync only changed files to a remote server over SSH — no rsync or native binaries required. Works on Windows, macOS, and Linux.

✨ Features

  • 🚀 Three simple commands

    • sync - Pull remote state + push local changes (one command to rule them all)
    • pull - Download remote file list and create/update manifest
    • push - Upload only changed files based on manifest
  • 🔄 Smart auto-pull No manifest? The sync command automatically pulls from remote first.

  • 🗑️ Optional remote deletion Use --delete (or XSYNC_DELETE=1) to remove remote files not present locally.

  • 🔐 SSH support

    • OpenSSH private key
    • Password auth
    • Custom ports
    • Works perfectly on Windows (including key conversion from .ppk)
  • ⚙️ Flexible configuration

    • Config file support (xsync.config.js or xsync.config.ts)
    • Environment variables
    • .env file support
  • 📦 Bundled CLI (single JS file via esbuild)

📦 Installing in Your Project

In your project (the one you want to sync from):

npm install -D x-rsync ssh2-sftp-client

Add to your package.json:

{
  "scripts": {
    "sync": "x-rsync sync ./dist",
    "pull": "x-rsync pull",
    "push": "x-rsync push ./dist"
  }
}

Or just the essentials:

{
  "scripts": {
    "sync": "x-rsync sync ./dist"
  }
}

⚙️ Configuration

You can configure x-rsync using either a config file (recommended) or environment variables.

Create xsync.config.js in your project root:

export default {
  host: "your.server.ip",
  user: "root",
  port: 22,
  remoteDir: "/var/www/website",
  privateKeyPath: "C:/Users/you/.ssh/id_rsa",
  // OR use password:
  // password: "your_password",

  // Optional settings:
  delete: false,  // set to true to delete remote files not present locally
  fast: false,    // set to true to skip hashing (compare size+mtime only)

  // Exclude/Include patterns (glob syntax):
  exclude: [
    "node_modules/**",
    "config/**",
    "*.log"
  ],
  include: [
    "config/production.json"  // include this even if excluded by exclude patterns
  ]
};

Or use TypeScript (xsync.config.ts):

export default {
  host: "your.server.ip",
  user: "root",
  port: 22,
  remoteDir: "/var/www/website",
  privateKeyPath: "~/.ssh/id_rsa",
  delete: false,
  fast: false,
  exclude: ["node_modules/**", ".git/**"],
  include: ["config/production.json"]
};

Option 2: Environment Variables

Set these before running sync. Environment variables override config file settings.

Minimum:

XSYNC_HOST=your.server.ip
XSYNC_USER=root
XSYNC_REMOTE_DIR=/var/www/website

Authentication (choose ONE):

# Using a private key (recommended)
XSYNC_PRIVATE_KEY_PATH=C:/Users/you/.ssh/id_rsa

# OR using a password
XSYNC_PASSWORD=your_password

Optional:

XSYNC_PORT=22
XSYNC_DELETE=1   # enable deletes during sync
XSYNC_EXCLUDE="node_modules/**,.git/**,*.log"  # comma-separated glob patterns
XSYNC_INCLUDE="config/production.json"  # comma-separated glob patterns

Option 3: .env File

Create a .env file in your project root:

XSYNC_HOST=your.server.ip
XSYNC_USER=root
XSYNC_REMOTE_DIR=/var/www/website
XSYNC_PRIVATE_KEY_PATH=~/.ssh/id_rsa

🚀 Usage

Command Overview

x-rsync provides three commands:

x-rsync sync <localDir>

Combines pull + push into one command:

  • Checks if manifest exists
  • If no manifest: runs pull to download remote file list
  • Runs push to upload changed files

Example:

npm run sync         # sync current directory
npm run sync -- ./dist   # sync ./dist directory

pull - Download remote file list

x-rsync pull

Connects to your remote server, scans all files, and creates/updates .xsync/manifest.json. Use this when:

  • You want to manually update the manifest from remote
  • Someone made changes directly on the server
  • You're setting up sync for the first time

push - Upload changed files

x-rsync push <localDir>

Scans your local directory, compares with manifest, and uploads only changed files. Use this when:

  • You already have a manifest and just want to push changes
  • You want more control over the sync process

Note: Most of the time, you'll just use sync - it handles everything automatically!

Fast Mode

For faster syncs (with slightly lower accuracy), use the --fast flag or set fast: true in your config file:

Via CLI flag:

npm run sync -- --fast

Via config file:

export default {
  // ... other config
  fast: true
};

Fast mode:

  • Skips SHA-256 hashing
  • Compares only file size and modification time (mtime)
  • Significantly faster for large codebases
  • May miss changes if file size and mtime are unchanged
  • CLI flag --fast overrides config file setting

Dry Run Mode

To preview what would be changed without actually uploading or deleting files:

npm run sync -- --dry

Dry run mode:

  • Scans local files and compares with manifest
  • Shows how many files would be uploaded/deleted
  • Does not connect to the server
  • Does not modify any files
  • Useful for testing before actual sync

Exclude/Include Patterns

Control which files are synced using glob patterns:

Via CLI flags:

# Exclude files
npm run sync -- --exclude="node_modules/**" --exclude=".git/**"

# Include files (overrides exclude)
npm run sync -- --exclude="config/*" --include="config/production.json"

Via config file:

export default {
  // ... other config
  exclude: [
    "node_modules/**",
    ".git/**",
    "*.log",
    "test/**"
  ],
  include: [
    "config/production.json",  // include this specific file
    "assets/critical/**"        // include this directory even if excluded
  ]
};

Via environment variables:

XSYNC_EXCLUDE="node_modules/**,.git/**,*.log"
XSYNC_INCLUDE="config/production.json"

How it works:

  • By default, all files are included
  • exclude patterns mark files to skip
  • include patterns override exclude - use this to include specific files that would otherwise be excluded
  • Example: --exclude="config/*" --include="config/production.json" excludes all config files except production.json
  • Patterns use minimatch glob syntax
  • Patterns are matched against the relative file path from the local directory

Common patterns:

  • src/**/*.{js,ts} all JS and TS files in src or src subdirectories
  • **/*.log - all .log files in any directory
  • node_modules/** - everything in node_modules
  • *.tmp - all .tmp files in root only
  • test/** - all files in test directory

🗑️ Deleting Remote Files

To remove remote files that no longer exist locally:

npm run sync -- --delete

Or set:

XSYNC_DELETE=1

🔐 Using SSH Keys on Windows

x-rsync does NOT support .ppk files (PuTTY format).

Convert to OpenSSH using PuTTYgen:

  • Open PuTTYgen
  • Load your .ppk
  • Go to: Conversions → Export OpenSSH key
  • Save as: id_rsa (or any name)
  • Use the saved file path in privateKeyPath (config file) or XSYNC_PRIVATE_KEY_PATH (env var)

📁 Project Structure

.xsync/manifest.json  # Remote server state (auto-generated on first sync)
dist/cli.js          # Bundled CLI (ESM)
dist/cli.cjs         # Bundled CLI (CommonJS)
src/
  cli.ts             # Entry point
  sync/              # Remote sync utilities
  shared.ts          # Shared utilities
  types.ts           # TypeScript types

🛠️ Development

Build the CLI:

npm run build

This bundles src/cli.tsdist/cli.cjs using esbuild.

📝 Example Workflow

Using Config File

1. Create xsync.config.js:

export default {
  host: "192.168.1.100",
  user: "root",
  privateKeyPath: "~/.ssh/id_rsa",
  remoteDir: "/var/www/myapp",
  fast: true  // Optional: enable fast mode by default
};

2. Use the CLI:

# Most common: just sync everything
npm run sync

# Sync with options
npm run sync -- --delete    # Delete remote files not in local
npm run sync -- --fast      # Skip hashing (faster, less accurate)
npm run sync -- --dry       # Preview changes without uploading

# Combine flags
npm run sync -- --fast --delete

# Manual control (advanced)
npm run pull                # Update manifest from remote
npm run push                # Push local changes only
npm run push -- --exclude="*.log"  # Push with exclusions

Using Environment Variables

# 1. Set up environment variables
export XSYNC_HOST=192.168.1.100
export XSYNC_USER=root
export XSYNC_PRIVATE_KEY_PATH=~/.ssh/id_rsa
export XSYNC_REMOTE_DIR=/var/www/myapp

# 2. Sync (first run will auto-pull from remote, then push changes)
npm run sync

📄 License

MIT

🤝 Contributing

Contributions welcome! Feel free to open issues or pull requests.

Keywords

sftp

FAQs

Package last updated on 08 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts