Overview
Sync Folds solves a fundamental limitation in Obsidian: fold states are stored inlocalStorage, which doesn’t sync across devices. This plugin intercepts localStorage operations and persists fold states to a file that syncs with your vault.
The Core Mechanism
The plugin operates through three key phases: interception, persistence, and synchronization.localStorage Interception
When the plugin loads, it intercepts Obsidian’s localStorage operations by overriding the native The plugin preserves the original methods and calls them first to maintain Obsidian’s normal behavior.
setItem and removeItem methods. This allows the plugin to detect every fold state change.Debounced Persistence
When a fold state changes, the plugin doesn’t save immediately. Instead, it uses a 150ms debounce to batch rapid changes and reduce file I/O.This means if you fold and unfold multiple headings quickly, only the final state is written to disk.
File-Based Synchronization
Fold states are persisted to
.obsidian/plugins/sync-folds/data.json. Since this file is part of your vault, any file sync solution (Obsidian Sync, iCloud, Git, etc.) will automatically sync it across devices.The plugin detects when this file changes externally and updates localStorage accordingly.Data Flow Diagram
Initial State Handling
When the plugin first loads, it intelligently decides whether to import or export:View initialization logic
View initialization logic
- If
data.jsoncontains fold states → import them to localStorage - If
data.jsonis empty → export current localStorage folds to the file
External Settings Change Detection
The plugin monitors for external changes to detect when fold states are synced from another device:The plugin maintains a
cachedFolds object to track the last known state. This allows it to efficiently detect what changed when the file is updated externally, avoiding unnecessary localStorage updates.Fold State Data Structure
Fold states are stored as JSON objects mapping file paths to fold information:The
folds field is stored as a stringified JSON object rather than a nested object. This is because Obsidian’s plugin data API serializes and deserializes the entire settings object.Performance Considerations
Debouncing
The 150ms debounce prevents excessive writes when you’re rapidly folding/unfolding content. Only the final state is persisted.
Cached State
The plugin caches the current fold state in memory to avoid re-reading the file on every localStorage operation.
Selective Updates
When external changes are detected, only modified fold states are updated in localStorage, not the entire state tree.
Original Method Binding
The original localStorage methods are bound and preserved, ensuring native performance for non-fold localStorage operations.
Enable/Disable Sync
The plugin respects theenableSync setting from settings.ts:
enableSync is false, the plugin skips:
- localStorage interception
- Debounced syncing
- File exports
- External change detection