# How OpenScreen Stores and Restores Recording Sessions Between Application Launches

> Learn how OpenScreen stores and restores recording sessions using JSON manifest files, ensuring your progress is saved and accessible across application launches.

- Repository: [Sid/openscreen](https://github.com/siddharthvaddem/openscreen)
- Tags: internals
- Published: 2026-04-03

---

**OpenScreen persists recording sessions as JSON manifest files saved alongside video files in the user's recordings directory, automatically restoring session state by reading these manifests when videos are reopened.**

OpenScreen is an Electron-based screen recording application that needs to maintain session metadata across restarts. When you record your screen, the application doesn't just save video files—it stores a small JSON *manifest* that captures the relationship between screen recordings, optional webcam feeds, and creation timestamps. This article explains exactly how the application handles recording session persistence, from the initial write to disk to the restoration logic triggered on subsequent launches.

## Storage Location and Manifest File Structure

OpenScreen saves all recording data in a dedicated user-data directory that persists between application launches.

### User Data Directory and File Naming

The storage root is defined in [`electron/main.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/main.ts) as `RECORDINGS_DIR`, which points to a "recordings" folder inside the user's application data directory【/cache/repos/github.com/siddharthvaddem/openscreen/main/electron/main.ts#L28-L33】. When you complete a recording named `foo.webm`, the system creates a corresponding manifest file named [`foo.session.json`](https://github.com/siddharthvaddem/openscreen/blob/main/foo.session.json) in the same directory. This naming convention is defined in [`electron/ipc/handlers.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/ipc/handlers.ts), where the suffix [`.session.json`](https://github.com/siddharthvaddem/openscreen/blob/main/.session.json) is appended to the base filename【/cache/repos/github.com/siddharthvaddem/openscreen/main/electron/ipc/handlers.ts#L23-L26】.

### Manifest Contents and Data Types

Each manifest stores a serialized `RecordingSession` object. The TypeScript interface is defined in [`src/lib/recordingSession.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/lib/recordingSession.ts) and includes:

- `screenVideoPath`: Absolute path to the screen recording
- `webcamVideoPath`: Optional absolute path to the webcam feed
- `createdAt`: ISO timestamp indicating when the session was created

The `RecordingSession` type definition lives in [`src/lib/recordingSession.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/lib/recordingSession.ts)【/cache/repos/github.com/siddharthvaddem/openscreen/main/src/lib/recordingSession.ts#L1-L18】, providing the contract that both the main and renderer processes rely on.

## Writing Sessions to Disk

When a recording finishes, the renderer process invokes `window.electronAPI.storeRecordedSession()`, which triggers the `storeRecordedSessionFiles` function in [`electron/ipc/handlers.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/ipc/handlers.ts)【/cache/repos/github.com/siddharthvaddem/openscreen/main/electron/ipc/handlers.ts#L124-L154】. This handler performs four critical operations:

1. Writes the screen video (and optional webcam video) to `RECORDINGS_DIR`
2. Constructs a `RecordingSession` object with the current timestamp
3. Serializes the object to JSON and writes it to `${baseName}.session.json`
4. Updates the in-memory `currentRecordingSession` state via `setCurrentRecordingSessionState` so the UI immediately reflects the new session

Here is how you store a session from the renderer process:

```typescript
// Store a session after recording finishes
await window.electronAPI.storeRecordedSession({
  screen: { fileName: "my-screen.webm", videoData: screenBlob },
  webcam: { fileName: "my-webcam.webm", videoData: webcamBlob }, // optional
});

```

## Restoring Sessions on Application Launch

OpenScreen automatically attempts to restore session state whenever you open a video file, ensuring continuity between application launches.

### Locating the Manifest

The restoration process begins with `getSessionManifestPathForVideo` in [`electron/ipc/handlers.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/ipc/handlers.ts), which derives the manifest path from the video filename. This helper intelligently strips "-webcam" suffixes if present, ensuring that opening either the screen or webcam video resolves to the same session manifest【/cache/repos/github.com/siddharthvaddem/openscreen/main/electron/ipc/handlers.ts#L72-L78】.

### Path Normalization and Validation

The `loadRecordedSessionForVideoPath` function handles the actual restoration logic【/cache/repos/github.com/siddharthvaddem/openscreen/main/electron/ipc/handlers.ts#L80-L98】. It reads the manifest file, parses the JSON, normalizes paths (handling `file://` URL prefixes), and verifies that the stored `screenVideoPath` matches the file the user actually opened. If validation passes, it returns a fully populated `RecordingSession` object; otherwise, it returns `null`.

When the renderer calls `set-current-video-path` (via `window.electronAPI.setCurrentVideoPath()`), the main process invokes `loadRecordedSessionForVideoPath`. If a valid manifest exists, the session state is restored immediately; if not, a fresh `RecordingSession` is created containing only the `screenVideoPath`【/cache/repos/github.com/siddharthvaddem/opensscreen/main/electron/ipc/handlers.ts#L37-L46】.

Here is how to open a video and retrieve its session:

```typescript
// Open a video file – main process auto-loads its session
await window.electronAPI.setCurrentVideoPath(selectedPath);

// Retrieve the current session to display metadata
const { success, session } = await window.electronAPI.getCurrentRecordingSession();
if (success) {
  console.log("Screen video:", session.screenVideoPath);
  console.log("Webcam video:", session.webcamVideoPath);
  console.log("Created at:", session.createdAt);
}

```

## In-Memory Session Management

While the manifest files provide disk persistence, OpenScreen maintains a single source of truth during runtime through the `currentRecordingSession` variable declared in [`electron/ipc/handlers.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/ipc/handlers.ts)【/cache/repos/github.com/siddharthvaddem/opensscreen/main/electron/ipc/handlers.ts#L34-L35】. The helper function `setCurrentRecordingSessionState` updates this variable whenever sessions change, ensuring all IPC handlers access consistent state without redundant disk reads.

The preload script ([`electron/preload.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/preload.ts)) exposes three critical IPC channels for session management:
- `set-current-video-path`: Triggers session restoration when opening files
- `get-current-recording-session`: Returns the in-memory session object
- `get-current-video-path`: Returns just the screen video path

## Summary

- **Storage Location**: Session manifests are saved in `RECORDINGS_DIR` (defined in [`electron/main.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/main.ts)) as `*.session.json` files alongside their corresponding video files.
- **Manifest Structure**: JSON files contain serialized `RecordingSession` objects with paths to screen/webcam videos and creation timestamps.
- **Persistence Logic**: The `storeRecordedSessionFiles` function in [`electron/ipc/handlers.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/ipc/handlers.ts) handles atomic writes of video data and JSON manifests.
- **Restoration Logic**: `loadRecordedSessionForVideoPath` validates and loads manifests when videos are opened, with path normalization for cross-platform compatibility.
- **Runtime State**: The `currentRecordingSession` variable provides fast in-memory access, synchronized with disk state via `setCurrentRecordingSessionState`.

## Frequently Asked Questions

### What happens if the session JSON file is deleted or corrupted?

If the manifest file is missing or contains invalid JSON, `loadRecordedSessionForVideoPath` returns `null`, and the application creates a fresh `RecordingSession` containing only the screen video path. The video file remains playable, but metadata like the original creation timestamp and webcam recording path will be lost.

### Can recording sessions be moved to a different folder and still restored?

Yes, provided the manifest is moved alongside the video files. However, the `screenVideoPath` stored in the JSON must match the actual path where the file is opened. If you move files to a new location, the path validation in `loadRecordedSessionForVideoPath` will fail, and the app will treat the video as a new recording without historical session data.

### How does OpenScreen handle webcam recordings in session restoration?

The `RecordingSession` type includes an optional `webcamVideoPath` field. When restoring, the app reads this path from the manifest. The naming logic in `getSessionManifestPathForVideo` strips "-webcam" suffixes to ensure that opening either the screen or webcam video resolves to the same session file, maintaining the relationship between paired recordings.

### Where is the recordings directory located on my system?

The `RECORDINGS_DIR` is resolved using Electron's `app.getPath('userData')` with a "recordings" subdirectory appended. On Windows, this typically resides in `%APPDATA%/OpenScreen/recordings`; on macOS, `~/Library/Application Support/OpenScreen/recordings`; and on Linux, `~/.config/OpenScreen/recordings`. This path is defined in [`electron/main.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/electron/main.ts) and created automatically if it doesn't exist.