# How to Export Data from PI Desktop: Complete Guide to Workspace Backup

> Export data from PI Desktop effortlessly. This guide details workspace backup using JSON export via Electron and Node.js APIs for secure data management.

- Repository: [Lan/PI-Desktop](https://github.com/vastsa/PI-Desktop)
- Tags: how-to-guide
- Published: 2026-09-12

---

**PI Desktop exports your workspace to a prettified JSON file via an IPC call from the renderer to the main Electron process, writing the serialized state to a user-selected path using Node.js file system APIs.**

PI Desktop is an Electron-based application that stores your projects, notes, plugins, and configuration in a JSON-based workspace model. When you need to backup or migrate your data, the application provides both UI-driven and programmatic methods to export data from PI Desktop using internal IPC handlers and native file dialogs.

## Understanding the Export Architecture

PI Desktop uses a standard Electron architecture split between the **main process** and **renderer process**. The workspace state lives in the main process memory, managed by functions defined in [`packages/shared/src/protocol.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/protocol.ts).

When you initiate an export, the renderer process sends an IPC message (`export-data`) to the main process. The handler in [`apps/desktop/electron/main/user-mcp.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/user-mcp.ts) retrieves the current workspace object, serializes it to formatted JSON, and writes it to disk using Node.js `fs` APIs.

## Exporting via the User Interface

The UI export flow begins when you select **File → Export** from the application menu. The renderer process opens a native save dialog and invokes the `export-data` channel.

```typescript
// apps/desktop/electron/shared/plugin-panel-chrome.ts
async function exportWorkspace() {
  const { filePath } = await window.electron.showSaveDialog({
    title: 'Export PI Desktop Data',
    defaultPath: 'pi-workspace.json',
    filters: [{ name: 'JSON', extensions: ['json'] }]
  });
  if (filePath) {
    await window.electron.invoke('export-data', filePath);
    window.showToast('Workspace exported successfully');
  }
}

```

This code uses `window.electron.showSaveDialog` to prompt for a destination, then calls `window.electron.invoke('export-data', filePath)` to trigger the main process handler. The `filters` array restricts the output to `.json` files.

## Main Process Export Handler

The actual serialization and file writing occur in the main process. The `ipcMain.handle` listener in [`apps/desktop/electron/main/user-mcp.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/user-mcp.ts) receives the file path, retrieves the current workspace state, and writes the JSON payload.

```typescript
// apps/desktop/electron/main/user-mcp.ts
import { ipcMain } from 'electron';
import { getWorkspace } from '../../packages/shared/src/protocol';
import { promises as fs } from 'fs';

ipcMain.handle('export-data', async (_event, filePath: string) => {
  const workspace = getWorkspace();                 // ← retrieves current state
  const data = JSON.stringify(workspace, null, 2); // ← serialises to JSON
  await fs.writeFile(filePath, data, 'utf‑8');      // ← writes to chosen file
  return true;
});

```

The `getWorkspace()` function fetches the in-memory workspace object from the shared protocol layer. `JSON.stringify(workspace, null, 2)` produces human-readable output with 2-space indentation. The handler uses `fs.promises.writeFile` for asynchronous, non-blocking I/O.

## Command-Line and Automated Exports

For headless environments, CI pipelines, or Linux distribution packaging, PI Desktop provides `scripts/export-linux-asar.mjs`. This script programmatically exports the workspace before building an ASAR archive.

```typescript
// scripts/export-linux-asar.mjs
import { build } from 'electron-builder';
import { exportWorkspace } from '../apps/desktop/electron/main/user-mcp.js';

async function main() {
  // Ensure the latest workspace is persisted
  await exportWorkspace('/tmp/pi-workspace.json');

  // Build ASAR package for Linux
  await build({
    config: {
      appId: 'com.vastsa.pidesktop',
      linux: { target: 'AppImage' },
      directories: { output: 'dist/linux' },
    },
  });
}
main().catch(console.error);

```

This approach imports the `exportWorkspace` function directly from the main process module, allowing you to export data from PI Desktop without launching the full GUI. The script first writes the workspace to [`/tmp/pi-workspace.json`](https://github.com/vastsa/PI-Desktop/blob/main//tmp/pi-workspace.json), then packages the application using `electron-builder`.

## Data Structure and File Format

The exported file is a UTF-8 encoded JSON document containing the complete workspace state. According to the protocol definitions in [`packages/shared/src/protocol.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/protocol.ts), the payload includes:

- **Projects** – Your organized project hierarchies
- **Notes** – All user-created notes and documents
- **Plugins** – Installed plugin configurations and state
- **Settings** – Application preferences and UI state

The output uses **prettified JSON** (`null, 2` spacing), making the file human-readable and suitable for version control systems like Git.

## Summary

- **IPC Architecture**: Export uses Electron's `ipcRenderer.invoke` and `ipcMain.handle` to communicate between UI and main process
- **Entry Point**: The UI code in [`apps/desktop/electron/shared/plugin-panel-chrome.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/shared/plugin-panel-chrome.ts) triggers the save dialog and IPC call
- **Core Logic**: [`apps/desktop/electron/main/user-mcp.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/user-mcp.ts) contains the `export-data` handler and `exportWorkspace` function that serializes data
- **Data Source**: [`packages/shared/src/protocol.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/protocol.ts) defines the workspace structure accessed via `getWorkspace()`
- **Automation**: `scripts/export-linux-asar.mjs` demonstrates programmatic export for build pipelines
- **Output Format**: Standard JSON with 2-space indentation, default filename [`pi-workspace.json`](https://github.com/vastsa/PI-Desktop/blob/main/pi-workspace.json)

## Frequently Asked Questions

### Where is the export data format defined in PI Desktop?

The data structures for the workspace, including projects, notes, and plugins, are defined in [`packages/shared/src/protocol.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/protocol.ts). This shared package ensures consistency between the main process, renderer process, and any CLI scripts that import the workspace types.

### Can I export PI Desktop data without opening the GUI?

Yes. You can import the `exportWorkspace` function from [`apps/desktop/electron/main/user-mcp.js`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/user-mcp.js) (or `.ts` when transpiled) into a Node.js script, as demonstrated in `scripts/export-linux-asar.mjs`. This allows you to programmatically export the workspace state for backup or migration without launching the Electron window.

### What data is included in the exported JSON file?

The export contains the complete workspace object retrieved by `getWorkspace()`, which includes all user projects, notes, plugin configurations, and application settings. The JSON is serialized with `JSON.stringify(workspace, null, 2)` to preserve readability and structure.

### How does PI Desktop validate the export file path?

The application relies on Electron's native `showSaveDialog` to validate the destination path in UI mode, which returns a validated absolute path or `undefined` if the user cancels. In programmatic exports, the script passes the path directly to `fs.promises.writeFile`, and errors are caught via standard Node.js exception handling.