How to Export Data from PI Desktop: Complete Guide to Workspace Backup
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.
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 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.
// 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 receives the file path, retrieves the current workspace state, and writes the JSON payload.
// 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.
// 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, 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, 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.invokeandipcMain.handleto communicate between UI and main process - Entry Point: The UI code in
apps/desktop/electron/shared/plugin-panel-chrome.tstriggers the save dialog and IPC call - Core Logic:
apps/desktop/electron/main/user-mcp.tscontains theexport-datahandler andexportWorkspacefunction that serializes data - Data Source:
packages/shared/src/protocol.tsdefines the workspace structure accessed viagetWorkspace() - Automation:
scripts/export-linux-asar.mjsdemonstrates programmatic export for build pipelines - Output Format: Standard JSON with 2-space indentation, default filename
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. 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 (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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →