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

@activebook/atom-updater

v2.0.2

Published

Node.js wrapper for atom-updater Go executable - provides atomic directory replacement with rollback capabilities

Readme

npm @activebook/atom-updater

A TypeScript Node.js wrapper for the atom-updater Go executable. This package provides atomic directory replacement with rollback capabilities for Node.js and Electron applications.

Features

  • Atomic Directory Updates: All-or-nothing directory replacement with automatic rollback
  • macOS .app Bundle Support: Specialized handling for directories containing .app bundles
  • Comprehensive Logging: Real-time console output + persistent log file
  • Robust Error Handling: Graceful failure handling with safe rollback
  • Smart Application Launching: Auto-detects and launches the correct application
  • Cross-Platform: Works on Windows, macOS, and Linux
  • Easy Integration: Simple TypeScript API for Node.js and Electron apps
  • Self-Contained: Bundled binaries eliminate external dependencies

How It Works

This package uses a bundled binary approach where platform-specific atom-updater executables are included directly in the npm package. When you install the package, you get:

  • The TypeScript wrapper code
  • Pre-compiled atom-updater binaries for your platform
  • Automatic binary detection and selection

The wrapper automatically finds and uses the correct binary for your platform and architecture, eliminating the need for separate downloads or installations.

Self-Updating Applications

For applications that need to update themselves, use the binDir parameter to copy the atom-updater binary to an external location first:

  1. Copy Phase: The bundled binary is copied to an external directory outside your app
  2. Update Phase: The external copy performs the atomic directory replacement
  3. Launch Phase: The new version of your application is launched

This approach prevents the updater from trying to replace itself during self-updates.

Installation

npm install @activebook/atom-updater

The package includes platform-specific atom-updater binaries, so no additional downloads are required. The wrapper automatically detects and uses the bundled binary for your platform and architecture.

Quick Start

import { AtomUpdater } from 'atom-updater';

const updater = new AtomUpdater();

// Check version
const version = await updater.getVersion();
console.log(`Atom updater version: ${version}`);

// Perform update
const result = await updater.update({
  pid: process.pid,
  currentAppDir: '/path/to/current/app',
  newAppDir: '/path/to/new/app/version'
});

if (result.success) {
  console.log('Update initiated successfully!');
  console.log(`Log file: ${result.logPath}`);

  // Exit immediately - atom-updater will handle the rest
  process.exit(0);
} else {
  console.error('Update failed to start:', result.error);
}

API Reference

AtomUpdater Class

Constructor

constructor(options?: AtomUpdaterOptions)

Options:

  • executablePath?: string - Custom path to the atom-updater executable
  • workingDirectory?: string - Working directory for the update process
  • verbose?: boolean - Enable verbose logging
  • logger?: (message: string) => void - Custom logger function

Methods

getVersion(): Promise<string>

Get the version of the atom-updater executable.

const version = await updater.getVersion();
update(config: UpdateConfig): Promise<UpdateResult>

Perform an atomic update by starting the atom-updater process as a detached background process. This method returns immediately - the actual update happens asynchronously after the calling process exits.

For self-updating applications, use the binDir parameter to copy the atom-updater binary to an external location first. This prevents the updater from trying to replace itself.

const result = await updater.update({
  pid: 12345,
  currentDir: '/path/to/current',
  newDir: '/path/to/new',
  appName: 'optional-app-name', // Optional
  binDir: '/tmp/atom-updater-external' // Optional: for self-updates
});

// The method returns immediately with success: true
// The calling application should exit immediately after this call
// atom-updater will wait for the exit, perform the update, and launch the new version
isAvailable(): Promise<boolean>

Check if the atom-updater executable is available.

const available = await updater.isAvailable();
getExecutablePath(): string

Get the path to the executable being used.

Types

UpdateConfig

interface UpdateConfig {
  pid: number;           // Process ID to wait for exit
  currentAppDir: string; // Path to current application directory
  newAppDir: string;     // Path to new application directory
  appName?: string;      // Optional specific executable to launch
  timeout?: number;      // Optional timeout for the update process
  binDir?: string;       // Optional external directory to copy atom-updater binary (for self-updates)
}

UpdateResult

interface UpdateResult {
  success: boolean;      // Whether the update process was started successfully
  logPath?: string;      // Path to the log file (atom-updater.log)
  launchedPid?: number;  // Process ID of the atom-updater process
  // Note: version and error fields are not used in the bundled binary approach
}

Update Process Flow

With the bundled binary approach, the update process follows this sequence:

  1. Your app calls updater.update(config) with paths and PID
  2. Wrapper starts atom-updater as a detached background process
  3. Method returns immediately with success: true
  4. Your app exits (via app.quit() in Electron or process.exit() in Node.js)
  5. atom-updater waits for your app process to fully exit
  6. atom-updater performs the atomic directory replacement
  7. atom-updater launches the new version of your application
  8. atom-updater exits

This approach ensures safe, atomic updates without the chicken-and-egg problem of waiting for completion.

Integration Examples

Electron Application

import { AtomUpdater } from 'atom-updater';
import { app } from 'electron';

class AppUpdater {
  private updater = new AtomUpdater({ verbose: true });

  async checkForUpdates() {
    try {
      const available = await this.updater.isAvailable();
      if (!available) {
        console.error('atom-updater executable not found');
        return;
      }

      const version = await this.updater.getVersion();
      console.log(`Using atom-updater version: ${version}`);
    } catch (error) {
      console.error('Failed to check updater:', error);
    }
  }

  async performUpdate(newVersionPath: string) {
    try {
      const result = await this.updater.update({
        pid: process.pid,
        currentAppDir: __dirname, // Electron app directory
        newAppDir: newVersionPath
      });

      if (result.success) {
        console.log('Update initiated successfully!');
        console.log(`Log file: ${result.logPath}`);

        // Exit immediately - atom-updater will handle the rest
        // It will wait for this process to exit, perform the update,
        // and launch the new version automatically
        app.quit();
      } else {
        console.error('Update failed to start:', result.error);
      }
    } catch (error) {
      console.error('Update error:', error);
    }
  }
}

Self-Updating Electron Application

import { AtomUpdater } from 'atom-updater';
import { app } from 'electron';
import path from 'path';
import os from 'os';

class AppUpdater {
  private updater = new AtomUpdater({ verbose: true });

  async performSelfUpdate(newVersionPath: string) {
    try {
      // For self-updates, copy the updater binary to an external directory
      const tempDir = os.tmpdir();
      const externalBinDir = path.join(tempDir, 'atom-updater-bin');

      const result = await this.updater.update({
        pid: process.pid,
        currentAppDir: __dirname, // Electron app directory
        newAppDir: newVersionPath,
        binDir: externalBinDir // Copy binary to external directory for self-update
      });

      if (result.success) {
        console.log('Self-update initiated successfully!');
        console.log(`External updater: ${externalUpdaterPath}`);
        console.log(`Log file: ${result.logPath}`);

        // Exit immediately - external updater will handle the rest
        app.quit();
      } else {
        console.error('Self-update failed to start:', result.error);
      }
    } catch (error) {
      console.error('Self-update error:', error);
    }
  }
}

Node.js Application

import { update, getVersion } from 'atom-updater';

async function performUpdate() {
  try {
    // Check if updater is available
    const version = await getVersion();
    console.log(`Using atom-updater ${version}`);

    // Perform update
    const result = await update({
      pid: process.pid,
      currentAppDir: process.cwd(),
      newAppDir: './updates/new-version'
    });

    if (result.success) {
      console.log('Update initiated successfully!');
      console.log(`Log file: ${result.logPath}`);

      // Exit immediately - atom-updater will handle the rest
      process.exit(0);
    } else {
      console.error('Update failed to start:', result.error);
    }
  } catch (error) {
    console.error('Update process failed:', error);
  }
}

Custom Executable Path

import { AtomUpdater } from 'atom-updater';

const updater = new AtomUpdater({
  executablePath: '/custom/path/to/atom-updater',
  verbose: true
});

Platform Support

  • Windows: amd64, 386 - bundled binaries included
  • macOS: amd64, arm64 (Apple Silicon) - bundled binaries included, optimized for .app bundles
  • Linux: amd64, arm64, 386 - bundled binaries included

The package includes platform-specific binaries, so no additional downloads are required.

Requirements

  • Node.js 14.0.0 or later
  • No additional dependencies - the atom-updater binary is bundled with the package

Error Handling

The package provides specific error classes for different failure scenarios:

import {
  AtomUpdaterError,
  ExecutableNotFoundError,
  UpdateFailedError
} from 'atom-updater';

try {
  await updater.update(config);
} catch (error) {
  if (error instanceof ExecutableNotFoundError) {
    console.error('atom-updater executable not found');
  } else if (error instanceof UpdateFailedError) {
    console.error('Update failed:', error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}

Logging

The atom-updater executable provides comprehensive logging:

  • Console Output: Real-time progress during updates
  • File Logging: Persistent log at ./atom-updater.log (auto-cleared on startup)
  • Debug Information: Timestamps and source file names for troubleshooting

The log file is created in the same directory as the atom-updater executable.