Client-Side Persistence (Dexie/IndexedDB)
Relevant source files
The following files were used as context for generating this wiki page:
The Client-Side Persistence system in Bolt manages the storage and retrieval of chat histories, message logs, and project file states directly within the user's browser. It utilizes a hybrid approach combining IndexedDB for structured metadata/message history and the Native File System API (via FileSystemDirectoryHandle) for direct project file manipulation.
This system ensures that user progress is maintained across sessions without relying on a centralized database, enabling a "local-first" development experience. It supports automatic synchronization between the editor state, the WebContainer's virtual filesystem, and the user's local disk.
Sources: app/lib/persistence/db.ts, app/lib/persistence/fileSystem.ts, app/lib/persistence/useChatHistory.ts
Core Architecture
The persistence layer is divided into two primary concerns: database management for chat metadata and filesystem management for actual code content.
IndexedDB Storage
Bolt uses a database named boltHistory with a single object store called chats. This store is indexed by both a unique id and a urlId for routing purposes.
Sources: app/lib/persistence/db.ts:11-23
Hybrid Persistence Flow
When a chat is loaded, the system attempts to prioritize the local filesystem (if a directory is selected) before falling back to IndexedDB.
Key Components and Logic
Database Operations
The db.ts module provides low-level asynchronous wrappers for standard IndexedDB operations.
| Function | Purpose | Data Source |
|---|---|---|
openDatabase | Initializes boltHistory DB and creates object stores/indexes. | db.ts:9-30 |
setMessages | Persists chat items to IndexedDB and triggers FS sync. | db.ts:49-83 |
getMessages | Hybrid fetch logic (FS first, then DB). | db.ts:85-112 |
getNextId | Determines the next numeric ID by scanning existing keys. | db.ts:141-152 |
FileSystem Integration
The fileSystem.ts module handles interactions with the browser's File System Access API. It manages directory handles and maps internal project paths to the user's local disk.
- Directory Selection: The
selectDirectoryfunction invokeswindow.showDirectoryPicker()and persists the handle reference in a NanoStore (selectedDirectoryHandle) and the folder name inlocalStorage. - Project Initialization: When a chat starts,
createProjectFilesparses assistant messages for<boltAction type="file">tags to write files to the chosen directory. - Change Detection:
checkForFileChangesrecursively traverses the selected directory to detect external modifications, which are then synced back to theWorkbenchStore.
Sources: app/lib/persistence/fileSystem.ts:54-85, app/lib/persistence/fileSystem.ts:192-230, app/lib/stores/workbench.ts:145-160
Synchronization Logic
The WorkbenchStore maintains synchronization between the EditorStore (UI), the FilesStore (WebContainer), and the FileSystem (Local Disk).
Data Models
ChatHistoryItem
This interface represents the structure stored in both IndexedDB and the .boltnew.json sidecar files.
| Field | Type | Description |
|---|---|---|
id | string | Primary key for the chat. |
urlId | string (optional) | Slug used in the browser URL. |
description | string (optional) | User-facing title derived from the first artifact. |
messages | Message[] | Array of Vercel AI SDK compatible message objects. |
timestamp | string | ISO string of the last modification. |
Sources: app/lib/persistence/useChatHistory.ts:10-16
Persistence Hooks and Stores
The application uses NanoStores for reactive state management of persistence status.
selectedDirectoryHandle: Holds theFileSystemDirectoryHandle. If null, the UI prompts for directory selection.chatId/description: Active chat metadata atoms.useChatHistoryHook: The primary interface for components to load history and trigger auto-saving of message logs.
Sources: app/lib/persistence/fileSystem.ts:7, app/lib/persistence/useChatHistory.ts:24-25, app/routes/_index.tsx:16-30
Conclusion
The persistence system in Bolt is designed for seamless local development. By leveraging IndexedDB for metadata and the File System API for code, it allows users to work on projects that persist across page reloads while remaining compatible with standard local development workflows. The system's ability to sync external changes ensures that modifications made in external editors are reflected in the Bolt workbench in real-time.