How katsu996/notion works
1. Overall shape
- This is a client-side Notion clone built with Next.js App Router and configured for static export. There is no backend API, database, or auth layer; all persistent state lives in the browser.
2. Execution boundary
- The app starts from app/layout.tsx and app/page.tsx, which provide the global shell and the main workspace.
- Because the project exports static files, the runtime boundary is the browser: UI interactions, persistence, search, and editing all happen locally.
3. State and persistence layer
- lib/store.tsx is the central application state layer, likely implemented as a React context/store.
- It is the main write path for the app: pages, blocks, favorites, trash, selection, and UI state are persisted to LocalStorage and rehydrated on load.
- lib/seed.ts provides initial data for first run or reset scenarios.
4. Domain model
- lib/types.ts defines the shared data model for pages and blocks.
- lib/blockDefs.ts appears to describe the supported block types and their behaviors, forming the contract between the editor UI and the stored document model.
5. Document editor subsystem
- components/editor/Editor.tsx is the core block editor container.
- EditableBlock.tsx handles per-block editing and rendering, while BlockMenu.tsx and SlashMenu.tsx provide block-level actions and / command insertion.
- The editor supports multiple block types, inline formatting, indentation, drag-and-drop reordering, and block type changes, all mediated through store updates.
6. Page and navigation UI
- components/Sidebar.tsx, Topbar.tsx, and PageHeader.tsx make up the main navigation chrome around the editor.
- The sidebar likely owns the page tree, favorites, trash access, and mobile drawer behavior.
- Page selection in the sidebar routes the editor focus to the currently active page in the shared store.
7. Page management and document hierarchy
- Pages are nested, so the data model is a tree of documents rather than a flat list.
- Subpages are represented as pages that are linked from within other pages, with UI support for duplication, moving, restoration, and permanent deletion through TrashPopover.tsx.
8. Search and global commands
- SearchModal.tsx implements a global page search entry point, triggered by the README-documented Ctrl/⌘ + K flow.
- It searches across page titles and body content, meaning the store must expose indexed or enumerable page data to the modal.
9. Visual metadata subsystem
- lib/emojis.ts and lib/covers.ts provide the page icon and cover options.
- These are presentation metadata attached to pages, not separate entities, and they feed the page header/sidebar rendering.
10. Reusable UI and iconography
- components/icons.tsx centralizes icon assets used by menus, navigation, and block controls.
- This keeps the editor, sidebar, and modals visually consistent while avoiding repeated icon definitions.
11. Styling and responsive behavior
- app/globals.css and Tailwind CSS v4 provide the app’s styling foundation.
- The README indicates dark mode and mobile-first behavior, so the UI layer is designed to adapt between desktop workspace and drawer-based mobile navigation.
12. Tooling and delivery
- scripts/smoke-test.mjs and scripts/screenshots.mjs suggest automated verification and visual capture for the static app.
- .github/workflows/deploy.yml builds the exported site and deploys it to GitHub Pages, making the deployment path entirely static-hosted.
Main entry points: store.tsx Store · page.tsx Workspace · Editor.tsx Editor · Sidebar.tsx Sidebar
Components 22
App shell
Next.js entry points, global styling, and static export boundary
- Layout · Root app wrapper and global providers
app/layout.tsx - Workspace · Main page that mounts the app experience
app/page.tsx - Global CSS · Base styling and responsive theme foundation
app/globals.css - Next config · Static export and app build settings
next.config.ts
State model
Shared document data, persistence, and seeded content
- Store · Central client-side state, persistence, and actions
lib/store.tsx - Types · Shared page and block document schema
lib/types.ts - Block defs · Supported block types and editor behaviors
lib/blockDefs.ts - Seed data · Bootstrap content for first run or reset
lib/seed.ts - Utils · Shared utility functions
lib/utils.ts
Editor
Block editing and document manipulation
- Editor · Main document editor container
components/editor/Editor.tsx - Block item · Per-block rendering and editing surface
components/editor/EditableBlock.tsx - Block menu · Block-level commands and transforms
components/editor/BlockMenu.tsx - Slash menu · Insert blocks via / commands
components/editor/SlashMenu.tsx
Navigation
Workspace chrome, search, and page lifecycle UI
- Sidebar · Page tree, favorites, trash access, and mobile drawer
components/Sidebar.tsx - Topbar · Top-level navigation and workspace controls
components/Topbar.tsx - Page header · Page title, icon, and cover presentation
components/PageHeader.tsx - Search · Modal for finding pages and content
components/SearchModal.tsx - Trash · Restore and permanent delete actions
components/TrashPopover.tsx - Icons · Shared iconography for menus and chrome
components/icons.tsx
Tooling
Build, deploy, and verification support
- Deploy · Static build and deployment workflow
.github/workflows/deploy.yml - Smoke test · Automated runtime sanity check
scripts/smoke-test.mjs - Screenshots · Visual capture for the static app
scripts/screenshots.mjs
Connections 27
- Layout → Workspace: renders · Layout wraps the main workspace
- Layout → Global CSS: loads · Global styles are applied at the app root
- Layout → Next config: builds with · App output follows static export settings
- Workspace → Store: uses · Workspace reads and mutates shared state
- Workspace → Editor: mounts · Main page places the document editor
- Workspace → Sidebar: shows · Workspace chrome includes navigation
- Workspace → Topbar: shows · Workspace chrome includes top-level controls
- Store → Types: models · State is structured by the shared document schema
- Store → Block defs: interprets · Block behavior is driven by block definitions
- Store → Seed data: initializes · Seed content is used for first load or reset
- Store → Utils: uses · Store logic shares utility helpers
- Editor → Block item: composes · Editor renders the list of editable blocks
- Editor → Block menu: opens · Editor exposes block actions
- Editor → Slash menu: inserts · Editor supports slash-command insertion
- Editor → Store: writes to · Edits persist through the central store
- Block item → Block defs: applies · Block type determines rendering and behavior
- Sidebar → Store: navigates · Page selection and tree state come from the store
- Sidebar → Trash: manages · Trash actions are surfaced from the sidebar
- Topbar → Search: opens · Global search is triggered from workspace controls
- Page header → Icons: uses · Header visuals reuse shared icons
- Sidebar → Icons: uses · Navigation controls reuse shared icons
- Block menu → Icons: uses · Menu actions use the shared icon set
- Search → Store: queries · Search scans pages and body content from state
- Page header → Store: reads · Header reflects active page metadata
- Deploy → Next config: deploys · Workflow builds the static export for Pages
- Smoke test → Workspace: checks · Smoke test validates the mounted app
- Screenshots → Workspace: captures · Screenshot script targets the rendered app