Global Stores
Relevant source files
The following files were used as context for generating this wiki page:
Global Stores in this project are built using nanostores, providing a reactive, framework-agnostic state management layer. These stores manage the lifecycle of the in-browser development environment, including the virtual filesystem (WebContainers), editor state, terminal instances, and UI theme. The architecture leverages both simple atom stores for primitive values and complex MapStore or class-based stores for structured data like file maps and LLM-generated artifacts.
The state is often synchronized with the WebContainer API, ensuring that the UI reflects the real-time state of the sandboxed Node.js environment. Many stores also implement Hot Module Replacement (HMR) persistence to maintain state across development reloads.
Sources: app/lib/stores/workbench.ts:1-20, app/lib/stores/files.ts:25-45, CONTRIBUTING.md:44-50
Workbench Store
The WorkbenchStore serves as the primary orchestrator for the development interface. It aggregates specialized stores (Files, Editor, Terminal, Previews) and manages the high-level state of the IDE-like "Workbench" component.
Architecture and Data Flow
The Workbench store manages "Artifacts," which represent logical units of work or code blocks generated by the AI. Each artifact contains an ActionRunner responsible for executing shell commands or file operations within the WebContainer.
The diagram shows how the WorkbenchStore acts as a central hub for specialized state containers and execution logic.
Sources: app/lib/stores/workbench.ts:31-45, app/lib/stores/workbench.ts:213-240
Key State Properties
| Property | Type | Description |
|---|---|---|
artifacts | MapStore | Stores LLM-generated artifacts and their associated action runners. |
showWorkbench | WritableAtom<boolean> | Controls the visibility of the workbench UI panel. |
currentView | WritableAtom<WorkbenchViewType> | Toggles between 'code' and 'preview' modes. |
unsavedFiles | WritableAtom<Set<string>> | Tracks paths of files with pending changes not yet written to the FS. |
Sources: app/lib/stores/workbench.ts:40-48
Files Store
The FilesStore manages the virtual filesystem. it maintains a reactive map of the entire workspace and synchronizes with the WebContainer's underlying file system.
File System Synchronization
The store initializes by watching the WebContainer's working directory (WORK_DIR). It processes events such as add_file, change, and remove_file to update a MapStore<FileMap>.
The sequence shows the bidirectional flow between the WebContainer filesystem and the reactive store.
Sources: app/lib/stores/files.ts:98-150, app/lib/stores/files.ts:74-90
Data Structures
- FileMap: A record where keys are file paths and values are
Direntobjects (either aFilewith content or aFolder). - ModifiedFiles: A private
Mapthat tracks the original content of files since the last user message, used to compute diffs for the LLM.
Sources: app/lib/stores/files.ts:16-25, app/lib/stores/files.ts:38-42
Editor Store
The EditorStore handles the state specific to the CodeMirror instances. It manages "EditorDocuments," which include the file content, binary status, and scroll positions.
Document Management logic
The store uses a computed store to derive the currentDocument based on the currently selectedFile path.
// Example of computed document derivation
this.currentDocument = computed([this.documents, this.selectedFile], (documents, selectedFile) => {
if (!selectedFile) return undefined;
return documents[selectedFile];
});
Sources: app/lib/stores/editor.ts:16-22
State Summary
| Component | Functionality |
|---|---|
documents | Stores EditorDocument objects for all open/known files. |
setDocuments | Initializes or updates the document map from a FileMap. |
updateScrollPosition | Persists the scroll state of a specific file to maintain context when switching tabs. |
Sources: app/lib/stores/editor.ts:11-14, app/lib/stores/editor.ts:57-70
Theme Store
The ThemeStore is a simple atom store that manages the 'light' or 'dark' mode of the application. It persists the selection to localStorage and updates the data-theme attribute on the <html> element.
Sources: app/lib/stores/theme.ts:1-32
Integration with UI
Stores are consumed in React components using the useStore hook from @nanostores/react. This ensures that components like Workbench.client.tsx or EditorPanel.tsx only re-render when the specific slice of state they depend on changes.
Sources: app/components/workbench/Workbench.client.tsx:49-60, app/root.tsx:64-70
The Global Stores architecture provides a centralized, reactive system that bridges the gap between the asynchronous WebContainer environment and the interactive UI, ensuring data consistency across file editing, terminal operations, and AI-driven code modifications.