Documentation
Architecture & Stack

Architecture & Stack

Plain is built exclusively as a client-side React single-page application (SPA). There is no backend server, and all data is processed in-memory or persisted locally via modern web storage APIs.

Tech Stack

The core technologies driving Plain are:

  • Framework: React 18, Vite 5
  • Styling: Tailwind CSS 3, lucide-react for icons
  • State Management: Zustand 5
  • Rich-Text Editor: Tiptap 3
  • Progressive Web App: vite-plugin-pwa
  • Testing: Playwright (e2e/), Vitest (vitest.config.js)

Project Structure

A typical development flow in Plain revolves around the src/ directory.

src/
├── components/   # UI elements: Sidebar, NoteList, NoteEditor
├── hooks/        # Reusable React hooks (e.g., useTheme)
├── storage/      # Storage adapters (Folder, OPFS, LocalStorage)
├── store/        # Global Zustand state and actions
├── utils/        # Note sorting, date formatters, export utilities
├── extensions/   # Tiptap custom extensions (PlainImage, etc.)
├── App.jsx       # The main application shell
└── main.jsx      # Vite entry point and Service Worker registration

State Management

State management lives primarily in src/store/useNotesStore.js. Zustand is used to provide an efficient, unopinionated store.

  • Notes are edited in-memory as HTML strings in the content field.
  • Note behavior (creation, pinning, trashing, restoring) is managed via global store actions.

PWA and Offline Support

Plain is configured as a Progressive Web App using vite-plugin-pwa.

  • Service Worker: Registration occurs in main.jsx.
  • Auto-Update: The Service Worker is configured with registerType: 'autoUpdate'.
  • Offline Mode: Built assets are aggressively cached by Workbox. There are no runtime API calls to fail, so the app remains fully functional without a network connection.

No Backend Interactions

Important: There are absolutely no cloud APIs, sync servers, user accounts, or backend interactions in this codebase. If you need cloud syncing, you rely on the user pointing the app at a folder synced by iCloud, Dropbox, Google Drive, or similar desktop clients.