npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

smt-studio

v2.0.2

Published

Salesforce Data Migration Studio - A tool to simplify Salesforce data migration tasks.

Readme

Salesforce Migration Studio

A modern web-based interface for Salesforce data migration — with real-time monitoring, AI-assisted analysis, data comparison, deletion candidate detection, and export capabilities.


Screenshots

Edit Load Plan

Edit plan

Compare Org Data

Compare Org Data) Compare Org Data-2)

CSV Generation

CSV Generation

Data Deletion in Target Org

Data Deletion in Target Org

AI SideKick

AI SIdeKick - 1  AI SIdeKick - 2

🌟 Features

🎨 Modern Web Interface

  • Dark Theme: Professional dark mode UI built with Tailwind CSS
  • Tab-Based Navigation: Organized workflow across 6 main sections
  • Split Pane Layout: Resizable Monaco editor on left, real-time terminal on right
  • Custom Dialogs: All confirmation and pause prompts are in-app modals (no browser alert/confirm)

🔐 Authentication

  • Authenticate source and target Salesforce orgs via Salesforce CLI (sf)
  • Org dropdown populated from sf org list — grouped by type (Production/Sandbox/Scratch)
  • Visual connection status card with alias, URL, and connected status
  • Supports both username and alias

📦 Object Selection

  • Search Functionality: Quickly find objects in large load plans
  • Bulk Selection: Select All / Deselect All respects the active search filter
  • Visual Indicators: Shows single-step vs multi-step objects
  • Keyboard Shortcuts: Ctrl+K / Cmd+K to focus search, Escape to clear

📋 Load Plan Management

  • Monaco Editor: Full VS Code editing experience with JSON syntax highlighting
  • File Upload: Load existing migration plans (.json)
  • Sample Plans: Quick-start with pre-built configurations
  • Auto-formatting: JSON validation and formatting on paste/type
  • Tracked Filename: Server remembers your uploaded filename for CLI command generation

⚙️ Generate Load Plan

  • Auto-describe any Salesforce object from an authenticated org
  • Generates Type 1 (relationship composite keys) and Type 2 (Global_Key__c) plans
  • Smart lookup key detection — checks if referenced objects have a Code field vs Name
  • Field summary table showing which fields are in the query and mappings
  • Copy / Download / Load directly into the Edit Plan editor

🔍 Data Comparison

  • SOQL Editor: Monaco-powered query editor with field autocomplete (via sf sobject describe)
  • Visual Tables: Compare records between source and target orgs
  • Advanced Features: Column sorting, search, pagination (10/25/50/100 rows), nested field support
  • Three Categories: Only in Source · Only in Target · In Both
  • Export: Download any category as CSV
  • CLI Helper: Personalized sf-data-util command with your actual credentials

🚀 Migration Operations

  • Validate Configuration: Check object/field accessibility before touching data
  • Generate CSV Files: Write insert/update CSVs without loading to target
  • Start Migration: Full migration with real-time progress; confirms via in-app dialog
  • Export to ZIP: Download source + target data as a compressed archive
  • Deletion Candidates: Find target records absent from source — one object at a time, paginated table with direct target-org record links, CSV download
  • CSV Output Folder: Optional path for all generated CSVs and all.zip (UI field + --csv-output-folder CLI flag; folder auto-created)
  • Per-Object Pause: After each object a modal popup lets you Continue or Stop

📟 Real-time Terminal

  • Live logs with color coding: info / success / warning / error
  • Per-Object Tabs: A tab is created for each object as it's processed; auto-switches during runs; "All" tab always available
  • Search: Live highlight as you type, navigate matches with ▲▼ or Enter / Shift+Enter, Escape to clear
  • Timestamps on every entry
  • Download logs as .txt
  • Clear terminal (resets tabs too)

✦ AI Sidekick (opt-in)

  • Slide-in panel with CHAT and SETTINGS tabs
  • Supports Ollama (local), Claude by Anthropic, OpenAI, xAI (Grok), Google Gemini
  • Ollama model list fetched live from /api/tags — full dropdown with all installed models
  • Context-aware system prompt: source org, target org, selected objects, full load plan with composite keys injected automatically
  • Multi-turn conversation history
  • Enable with --enable-ai server flag

🚀 Quick Start

Prerequisites

  • Node.js v14 or higher
  • Salesforce CLI (sf)
  • Authenticated Salesforce orgs

Installation

npm install -g smt-studio

📖 Usage Guide

Step 1 — Authenticate Orgs

  1. Open the 🔐 Authentication tab
  2. Click Refresh Org List — orgs are loaded from sf org list
  3. Select source org → Connect
  4. Select target org → Connect
  5. Status badges in the top nav turn green ✅

Step 2 — Select Objects

  1. Open the 📦 Select Objects tab
  2. Use the search box to filter (Ctrl+K / Cmd+K), then Select All or pick individually
  3. Click Next: Edit Plan →

Step 3 — Configure Load Plan

  1. Open the 📋 Edit Plan tab
  2. Load a Sample, Upload a JSON file, or use ⚙️ Generate Load Plan to auto-build one
  3. Edit in the Monaco editor, then 💾 Save Plan

Step 4 — Compare Data (recommended)

  1. Open the 🔍 Compare Data tab
  2. Select an object, optionally edit the SOQL query, click Compare
  3. Review the three category tables and download CSVs as needed

Step 5 — Execute Migration

  1. Open the 🚀 Migration tab
  2. (Optional) Enter a CSV Output Folder — leave blank to use the current working directory
  3. Choose an operation:

| Button | What it does | |---|---| | ✅ Validate Configuration | Checks object/field accessibility — no data touched | | 📄 Generate CSV Files | Writes insert/update CSVs, nothing loaded to target | | 🚀 Start Migration | Full migration with confirmation dialog | | 📦 Export to ZIP | Downloads source + target data as all.zip | | 🗑️ Deletion Candidates | Finds target records absent from source — object by object |

  1. After each object a Processing Paused popup appears — click ▶ Continue or ⛔ Stop
  2. Monitor progress in the terminal; switch per-object tabs or search logs

Deletion Candidates Workflow

  1. Click 🗑️ Deletion Candidates on the Migration tab
  2. Select one object from the dropdown
  3. Click 🔍 Find Candidates
  4. Review the table — Id values link directly to the target org record
  5. Click 📥 Download CSV to export the list for bulk deletion via Data Loader or the CLI

AI Sidekick (requires --enable-ai)

  1. Start the server with smt-studio --enable-ai
  2. Click ✦ AI Sidekick in the top nav
  3. Open SETTINGS, pick a provider, enter credentials / select model
  4. Switch to CHAT and ask anything about your migration

💻 Command Line Options

smt-studio  --help

# Custom port
smt-studio  --port 8080

# Bind to all interfaces
smt-studio  --host 0.0.0.0

# Default CSV output folder for all operations
smt-studio  --csv-output-folder /tmp/migration-csvs

# Enable AI Sidekick
smt-studio  --enable-ai

# Don't auto-open browser
smt-studio  --no-open

# Verbose logging
smt-studio  --verbose

# Combine
smt-studio  -p 8080 --host 0.0.0.0 --csv-output-folder ./output --enable-ai -v

smt-studio  -p 3333   --csv-output-folder ~/my-smt-csv-output --enable-ai

🎯 Sample Load Plan Format

[
  {
    "object": "Manufacturer__c",
    "compositeKeys": [
      "Global_Key__c"
    ],
    "compositeKeys_v1": [
      "Name"
    ],
    "query": "SELECT Global_Key__c, Name, Country__c FROM Manufacturer__c",
    "query_v1": "SELECT Name, Country__c FROM Manufacturer__c",
    "fieldMappings": {
      "Global_Key__c": "Global_Key__c",
      "Name": "Name",
      "Country__c": "Country__c"
    }
  },
  {
    "object": "VehicleCustomer__c",
    "compositeKeys": [
      "Global_Key__c"
    ],
    "compositeKeys_v1": [
      "Name"
    ],
    "query": "SELECT Global_Key__c, Name, Email__c FROM VehicleCustomer__c",
    "query_v1": "SELECT Name, Email__c FROM VehicleCustomer__c",
    "fieldMappings": {
      "Global_Key__c": "Global_Key__c",
      "Name": "Name",
      "Email__c": "Email__c"
    }
  },
  {
    "object": "Vehicle__c",
    "compositeKeys": [
      "Global_Key__c"
    ],
    "compositeKeys_v1": [
      "Name"
    ],
    "query": "SELECT Global_Key__c, Name, Model__c, Manufacturer__r.Global_Key__c, VehicleCustomer__r.Global_Key__c FROM Vehicle__c",
    "query_v1": "SELECT Name, Model__c, Manufacturer__r.Name, VehicleCustomer__r.Name FROM Vehicle__c",
    "fieldMappings": {
      "Global_Key__c": "Global_Key__c",
      "Name": "Name",
      "Model__c": "Model__c",
      "Manufacturer__c": {
        "lookup": {
          "object": "Manufacturer__c",
          "key": "Global_Key__c",
          "field": "Manufacturer__r.Global_Key__c"
        }
      },
      "VehicleCustomer__c": {
        "lookup": {
          "object": "VehicleCustomer__c",
          "key": "Global_Key__c",
          "field": "VehicleCustomer__r.Global_Key__c"
        }
      }
    }
  }
]

🔌 REST API Reference

| Method | Endpoint | Description | |---|---|---| | GET | /api/config | Get current configuration | | PUT | /api/selected-objects | Update selected objects | | POST | /api/auth | Authenticate source or target org | | POST | /api/load-plan | Save load plan JSON | | POST | /api/load-plan/file | Upload plan file (multipart) | | POST | /api/validate | Validate configuration | | POST | /api/migrate | Start migration (csvOutputFolder in body) | | POST | /api/generate-csv | Generate CSV files (csvOutputFolder in body) | | POST | /api/export | Export data to ZIP (csvOutputFolder in body) | | POST | /api/compare | Compare object data between orgs | | POST | /api/compare/custom | Compare with a custom SOQL query | | POST | /api/deletion-candidates | Records in target not in source for one object | | GET | /api/orgs | List authenticated orgs via sf org list | | GET | /api/sobjects | List SObject API names for an org | | GET | /api/describe/:sobject | Describe a Salesforce object's fields | | GET | /api/download/:filename | Download a generated file | | GET | /api/ai/status | Whether AI Sidekick is enabled | | GET | /api/ai/ollama/tags | Proxy Ollama /api/tags for model list | | POST | /api/ai/chat | Unified AI chat proxy (all providers) |


🔄 WebSocket Events (Socket.IO)

Server → Client

| Event | Payload | When | |---|---|---| | terminal | { timestamp, message } | Any console.log in server process | | object-start | { objectName } | Processing begins for an object (creates terminal tab) | | pause-prompt | { objectName, message, context } | After each object is processed | | migration-complete | { success, error? } | Migration finishes or fails | | csv-generation-complete | { success, error? } | CSV generation finishes or fails | | export-complete | { success, error? } | Export finishes or fails |

Client → Server

| Event | Payload | When | |---|---|---| | pause-response | { action: 'continue' \| 'stop' } | User clicks Continue or Stop in the popup |


🛠️ Configuration Storage

Persisted to ~/.migrationrc:

{
  "sourceConnection": { "instanceUrl": "...", "accessToken": "...", "username": "..." },
  "targetConnection": { "instanceUrl": "...", "accessToken": "...", "username": "..." },
  "loadPlan": [ ... ],
  "selectedObjects": [ "Account", "Contact" ],
  "loadPlanFilename": "my-migration.json"
}

⚠️ Never commit .migrationrc to version control — it contains access tokens.


⌨️ Keyboard Shortcuts

| Shortcut | Where | Action | |---|---|---| | Ctrl+K / Cmd+K | Select Objects tab | Focus object search | | Escape | Object search | Clear search | | Enter | Terminal search | Next match | | Shift+Enter | Terminal search | Previous match | | Escape | Terminal search | Clear search | | Enter | AI Sidekick chat | Send message | | Shift+Enter | AI Sidekick chat | New line | | Ctrl+Space | Monaco editor | Autocomplete | | Ctrl+F | Monaco editor | Find | | Alt+Shift+F | Monaco editor | Format JSON |


🔒 Security Notes

  1. Local use only by default (localhost binding)
  2. Use --host 0.0.0.0 only on trusted networks
  3. Access tokens are stored in ~/.migrationrc — protect this file
  4. Add .migrationrc to .gitignore
  5. AI provider API keys are held in browser memory only — never sent to or stored by the server beyond the proxied request
  6. For public-facing deployments, put a reverse proxy with HTTPS in front

🐛 Troubleshooting

Port already in use

smt-studio  -p 3001
# or kill the occupying process
lsof -ti:3000 | xargs kill -9

Salesforce CLI not found

npm install -g @salesforce/cli
sf version

Re-authenticate an org

sf org login web --alias my-org
sf org list

Ollama models not loading in AI Sidekick

# Confirm Ollama is running
curl http://localhost:11434/api/tags
# Then refresh the Base URL field in AI Sidekick Settings

AI Sidekick button not visible

# Server must be started with --enable-ai
smt-studio  --enable-ai

📝 Version

Version: 2.0.0
Author: Mohan Chinnappan

📄 License

MIT