# How Modly Handles Extension Backup Creation During Upgrades

> Modly creates extension backups during upgrades by atomically renaming the current installation. This ensures a reliable rollback path if the new version fails to install.

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: how-to-guide
- Published: 2026-08-15

---

**Modly safeguards existing extensions during upgrades by atomically renaming the current installation to a timestamped backup directory before swapping in the new version, ensuring a reliable rollback path if the installation fails.**

Modly is an Electron-based extension manager that prioritizes data safety during updates. When upgrading extensions, the application implements a robust backup strategy that prevents data loss and enables automatic recovery. This article examines how the `lightningpixel/modly` repository handles extension backup creation during upgrades through atomic file operations and staged deployments.

## The Staging Phase – Preparing for Safe Extension Upgrades

Before modifying any existing extension files, Modly prepares a **staging environment** to isolate the new version. The installer first copies the extracted extension into a temporary staging folder named `.modly-staging-<id>-<timestamp>`.

To detect interrupted installations, Modly writes an **incomplete marker** file (`.modly-incomplete`) into the staging directory:

```typescript
// Marker indicates installation is in progress
const incompleteMarker = join(stagingDir, EXT_INCOMPLETE_MARKER);
await writeFile(incompleteMarker, '');

```

This marker serves as a crash detection mechanism. If the application terminates unexpectedly, the startup reconciler can identify incomplete installations and trigger recovery procedures on the next launch.

## Atomic Backup Creation During Extension Upgrades

The actual backup creation occurs in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts) using helper functions from [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts). When an upgrade begins, Modly checks if the destination directory already exists:

```typescript
const destDir = resolveExtensionPathWithinRoot(extensionsDir, extensionId);
const backupDir = existsSync(destDir)
    ? buildExtensionBackupPath(extensionsDir, extensionId, String(Date.now()))
    : null;

```

The `buildExtensionBackupPath` function (defined in **extension-path-guard.ts**) constructs the backup path using a strict naming convention:

```typescript
// From electron/main/extension-path-guard.ts
export const EXT_BACKUP_PREFIX = '.modly-backup-';

export function buildExtensionBackupPath(
  rootDir: string,
  extensionId: unknown,
  suffix: string,
): string {
  const safeId = assertSafeExtensionId(extensionId);
  return resolvePathWithinRoot(rootDir, `${EXT_BACKUP_PREFIX}${safeId}-${suffix}`);
}

```

This generates paths like `.modly-backup-<extensionId>-<timestamp>`, ensuring each backup is unique and timestamped. If the destination exists, Modly performs an **atomic rename** to move the current version to the backup location:

```typescript
if (backupDir) {
  const parked = await renameWithRetry(destDir, backupDir, 'ext-install');
  if (!parked.ok) {
    // Abort installation – extension directory is locked
    throw new Error(`Cannot create backup: ${parked.error}`);
  }
}

```

The `renameWithRetry` utility handles transient file system locks and provides clear error messages when folders cannot be moved.

## Swapping and Activation Process

After securing the backup, Modly atomically promotes the staged version to the active extension directory:

```typescript
const activated = await renameWithRetry(stagingDir, destDir, 'ext-install');

```

This two-step rename sequence—first moving the old version to backup, then moving the new version to production—ensures that the `destDir` always contains a valid extension state, even if the process crashes between operations.

## Cleanup and Automatic Restoration

Once the new extension is successfully activated, Modly performs cleanup operations:

```typescript
// Remove the incomplete marker to signal success
const markerGone = await rmWithRetry(join(destDir, EXT_INCOMPLETE_MARKER), 'ext-install');

// Delete the backup only after confirming successful installation
if (backupDir && markerGone.ok) {
  void rmWithRetry(backupDir, 'ext-install');
}

```

If the installation fails at any point, Modly executes the inverse operation: it removes the partially-installed staging directory and **restores the backup** by renaming it back to `destDir`. The backup may also be restored automatically by the startup reconciler if a previous crash left an incomplete marker behind.

## Summary

- **Staging with crash detection**: Modly writes new extensions to temporary staging directories with `.modly-incomplete` markers to detect interrupted installations.
- **Timestamped backups**: The `buildExtensionBackupPath` function creates unique backup directories using the `.modly-backup-<id>-<timestamp>` naming pattern.
- **Atomic operations**: All critical file moves use `renameWithRetry` to ensure atomicity and handle file system locks gracefully.
- **Automatic recovery**: Backups are restored automatically if upgrades fail or if the application crashes during installation.
- **Cleanup on success**: Backup directories are deleted only after the incomplete marker is successfully removed, confirming a healthy installation.

## Frequently Asked Questions

### How does Modly name extension backup directories?

Modly uses the `buildExtensionBackupPath` function in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts) to generate backup names with the pattern `.modly-backup-<extensionId>-<timestamp>`. This ensures each backup is unique and traceable to a specific point in time.

### What happens if a Modly extension upgrade is interrupted?

If an upgrade is interrupted, the `.modly-incomplete` marker remains in the staging directory. On the next application launch, the startup reconciler detects this marker and automatically restores the previous version from the backup directory, rolling back any partial changes.

### Where is the extension backup logic implemented in Modly?

The core backup logic resides in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts), which orchestrates the upgrade flow. Helper functions for path construction and safety checks are defined in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts), including `buildExtensionBackupPath` and the `EXT_BACKUP_PREFIX` constant.

### Does Modly keep backups after successful extension upgrades?

No. Modly deletes the backup directory immediately after confirming the new extension installed correctly—that is, after successfully removing the `.modly-incomplete` marker. This prevents accumulation of outdated extension versions while ensuring the backup persists only as long as needed for recovery.