# How the draw.io Submodule Version Sync Script (sync.cjs) Works

> Discover how the drawio desktop sync.cjs script synchronizes submodule versions, ensuring package.json mirrors the canonical drawio VERSION while managing Electron auto-updates.

- Repository: [draw.io/drawio-desktop](https://github.com/jgraph/drawio-desktop)
- Tags: internals
- Published: 2026-03-05

---

**The `sync.cjs` script ensures the desktop application's [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json) version always mirrors the canonical version stored in the `drawio/VERSION` submodule while optionally configuring Electron auto-update behavior.**

In the `jgraph/drawio-desktop` repository, maintaining version alignment between the core editor and the desktop wrapper is critical for release integrity. The Node.js utility `sync.cjs` automates this synchronization by reading the submodule's version file and propagating that value into the application's metadata. This eliminates manual version drift and ensures that every desktop build accurately reflects the underlying draw.io editor version.

## Core Functionality of the Version Sync Script

The `sync.cjs` script operates as a pre-build utility that performs three distinct operations: path resolution and verification, version validation and injection, and auto-update configuration generation.

### Path Resolution and Submodule Verification

The script begins by resolving absolute paths to essential files. According to lines 4-7 of `sync.cjs`, it constructs paths to [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json), the generated [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js), and the `drawio/VERSION` file.

Before proceeding, the script verifies that the submodule is actually present. Lines 8-12 check for the existence of `drawio/VERSION`. If the file is missing—typically because the repository was cloned without the `--recursive` flag—the script prints an error message and aborts execution immediately.

### Version Validation and package.json Update

Once the submodule is confirmed, the script reads and validates the version string. Lines 14-21 read the `VERSION` file, trim whitespace, and validate the content against the semantic versioning pattern `X.Y.Z`. If the format does not match this pattern, the script exits with an error.

After validation, the script loads the current [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json) using Node's `require` function (line 23). It then overwrites the `version` field with the validated submodule version (line 25) and persists the changes back to disk with 2-space indentation formatting (line 27).

### Auto-Update Configuration Generation

Beyond version synchronization, the script controls the Electron auto-updater. Line 29 generates [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js), which exports a function that returns `true` when the script is invoked with the `disableUpdate` argument, or `false` otherwise. The main process imports this module to determine whether to activate automatic updates.

## Running the Synchronization Process

Developers execute the script via npm to align versions before building or releasing. The standard command reads the submodule version and updates [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json) accordingly:

```bash
npm run sync

```

To simultaneously disable automatic updates for the build, append the `disableUpdate` flag:

```bash
npm run sync -- disableUpdate

```

After execution, the generated [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js) contains the update preference:

```javascript
// Generated content when standard sync is run:
export function disableUpdate() { return false; }

// Generated content when disableUpdate flag is passed:
export function disableUpdate() { return true; }

```

## Integration with the Build Pipeline

The synchronization typically runs after pulling changes that affect the `drawio` submodule or immediately before creating a new release. By automating version propagation through `sync.cjs`, the `jgraph/drawio-desktop` maintainers ensure that the desktop wrapper version never diverges from the editor's canonical version defined in `drawio/VERSION`.

## Summary

- **`sync.cjs`** reads the canonical version from `drawio/VERSION` and writes it to [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json).
- The script validates version strings against the semantic versioning format `X.Y.Z` before applying changes.
- It generates [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js) to control Electron auto-updater behavior based on command-line arguments.
- Execution via `npm run sync` ensures the desktop build version aligns with the core editor submodule.
- The script aborts with an error if the submodule is missing, preventing builds with undefined versions.

## Frequently Asked Questions

### What happens if the drawio submodule is missing when running sync.cjs?

If `drawio/VERSION` does not exist, the script detects this condition at lines 8-12 and prints an error message before exiting. This prevents the build process from proceeding with an undefined or stale version number, ensuring that developers must properly initialize submodules using `git submodule update --init` before synchronizing.

### How does sync.cjs validate the version string?

The script reads the `VERSION` file and applies a regular expression match against the pattern `X.Y.Z` (semantic versioning). Lines 14-21 implement this validation, and if the content fails to match the expected format, the script terminates with an error rather than writing invalid data to [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json).

### Can I disable automatic updates using the sync script?

Yes. When you invoke the script with the `disableUpdate` argument (`npm run sync -- disableUpdate`), it generates [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js) containing a function that returns `true`. The Electron main process imports this function to determine whether to skip auto-update checks. Without this flag, the generated function returns `false`, enabling automatic updates.

### Where does sync.cjs write the version information?

The script writes the validated version to the `version` field in [`package.json`](https://github.com/jgraph/drawio-desktop/blob/main/package.json) at the repository root. It also writes the update configuration to [`src/main/disableUpdate.js`](https://github.com/jgraph/drawio-desktop/blob/main/src/main/disableUpdate.js). The source of truth remains `drawio/VERSION` inside the submodule, which the script reads but never modifies.