# katsu996/notion architecture

> Architecture diagram of the GitHub repository katsu996/notion, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/katsu996/notion
- Repository: https://github.com/katsu996/notion

## Overview

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: [`lib/store.tsx`](https://github.com/katsu996/notion/blob/main/lib/store.tsx) (Store), [`app/page.tsx`](https://github.com/katsu996/notion/blob/main/app/page.tsx) (Workspace), [`components/editor/Editor.tsx`](https://github.com/katsu996/notion/blob/main/components/editor/Editor.tsx) (Editor), [`components/Sidebar.tsx`](https://github.com/katsu996/notion/blob/main/components/Sidebar.tsx) (Sidebar)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_app["App shell"]
  node_node_app_layout["Layout<br/>Next.js shell<br/>[layout.tsx]"]
  node_node_app_page["Workspace<br/>Next.js entry<br/>[page.tsx]"]
  node_node_styles["Global CSS<br/>styles<br/>[globals.css]"]
  node_node_nextconfig["Next config<br/>build config<br/>[next.config.ts]"]
end

subgraph group_group_state["State model"]
  node_node_store[("Store<br/>react state<br/>[store.tsx]")]
  node_node_types["Types<br/>data model<br/>[types.ts]"]
  node_node_blockdefs["Block defs<br/>block contract<br/>[blockDefs.ts]"]
  node_node_seed["Seed data<br/>initial content<br/>[seed.ts]"]
  node_node_utils["Utils<br/>helpers<br/>[utils.ts]"]
end

subgraph group_group_editor["Editor"]
  node_node_editor["Editor<br/>[Editor.tsx]"]
  node_node_editable_block["Block item<br/>editable block<br/>[EditableBlock.tsx]"]
  node_node_block_menu["Block menu<br/>block actions<br/>[BlockMenu.tsx]"]
  node_node_slash_menu["Slash menu<br/>command palette<br/>[SlashMenu.tsx]"]
end

subgraph group_group_nav["Navigation"]
  node_node_sidebar["Sidebar<br/>page nav<br/>[Sidebar.tsx]"]
  node_node_topbar["Topbar<br/>workspace chrome<br/>[Topbar.tsx]"]
  node_node_pageheader["Page header<br/>page chrome<br/>[PageHeader.tsx]"]
  node_node_search["Search<br/>[SearchModal.tsx]"]
  node_node_trash["Trash<br/>page lifecycle<br/>[TrashPopover.tsx]"]
  node_node_icons["Icons<br/>icon set<br/>[icons.tsx]"]
end

subgraph group_group_tooling["Tooling"]
  node_node_github_workflow["Deploy<br/>github pages<br/>[deploy.yml]"]
  node_node_smoke["Smoke test<br/>verification<br/>[smoke-test.mjs]"]
  node_node_shots["Screenshots<br/>capture script<br/>[screenshots.mjs]"]
end

node_node_app_layout -->|"renders"| node_node_app_page
node_node_app_layout -->|"loads"| node_node_styles
node_node_app_layout -.->|"builds with"| node_node_nextconfig
node_node_app_page -->|"uses"| node_node_store
node_node_app_page -->|"mounts"| node_node_editor
node_node_app_page -->|"shows"| node_node_sidebar
node_node_app_page -->|"shows"| node_node_topbar
node_node_store -->|"models"| node_node_types
node_node_store -->|"interprets"| node_node_blockdefs
node_node_store -->|"initializes"| node_node_seed
node_node_store -.->|"uses"| node_node_utils
node_node_editor -->|"composes"| node_node_editable_block
node_node_editor -->|"opens"| node_node_block_menu
node_node_editor -->|"inserts"| node_node_slash_menu
node_node_editor -->|"writes to"| node_node_store
node_node_editable_block -->|"applies"| node_node_blockdefs
node_node_sidebar -->|"navigates"| node_node_store
node_node_sidebar -->|"manages"| node_node_trash
node_node_topbar -->|"opens"| node_node_search
node_node_pageheader -.->|"uses"| node_node_icons
node_node_sidebar -.->|"uses"| node_node_icons
node_node_block_menu -.->|"uses"| node_node_icons
node_node_search -->|"queries"| node_node_store
node_node_pageheader -->|"reads"| node_node_store
node_node_github_workflow -->|"deploys"| node_node_nextconfig
node_node_smoke -.->|"checks"| node_node_app_page
node_node_shots -.->|"captures"| node_node_app_page

click node_node_app_layout "https://github.com/katsu996/notion/blob/main/app/layout.tsx"
click node_node_app_page "https://github.com/katsu996/notion/blob/main/app/page.tsx"
click node_node_styles "https://github.com/katsu996/notion/blob/main/app/globals.css"
click node_node_store "https://github.com/katsu996/notion/blob/main/lib/store.tsx"
click node_node_types "https://github.com/katsu996/notion/blob/main/lib/types.ts"
click node_node_blockdefs "https://github.com/katsu996/notion/blob/main/lib/blockDefs.ts"
click node_node_seed "https://github.com/katsu996/notion/blob/main/lib/seed.ts"
click node_node_utils "https://github.com/katsu996/notion/blob/main/lib/utils.ts"
click node_node_editor "https://github.com/katsu996/notion/blob/main/components/editor/Editor.tsx"
click node_node_editable_block "https://github.com/katsu996/notion/blob/main/components/editor/EditableBlock.tsx"
click node_node_block_menu "https://github.com/katsu996/notion/blob/main/components/editor/BlockMenu.tsx"
click node_node_slash_menu "https://github.com/katsu996/notion/blob/main/components/editor/SlashMenu.tsx"
click node_node_sidebar "https://github.com/katsu996/notion/blob/main/components/Sidebar.tsx"
click node_node_topbar "https://github.com/katsu996/notion/blob/main/components/Topbar.tsx"
click node_node_pageheader "https://github.com/katsu996/notion/blob/main/components/PageHeader.tsx"
click node_node_search "https://github.com/katsu996/notion/blob/main/components/SearchModal.tsx"
click node_node_trash "https://github.com/katsu996/notion/blob/main/components/TrashPopover.tsx"
click node_node_icons "https://github.com/katsu996/notion/blob/main/components/icons.tsx"
click node_node_github_workflow "https://github.com/katsu996/notion/blob/main/.github/workflows/deploy.yml"
click node_node_smoke "https://github.com/katsu996/notion/blob/main/scripts/smoke-test.mjs"
click node_node_shots "https://github.com/katsu996/notion/blob/main/scripts/screenshots.mjs"
click node_node_nextconfig "https://github.com/katsu996/notion/blob/main/next.config.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_app_layout,node_node_app_page,node_node_styles,node_node_nextconfig toneBlue
class node_node_store,node_node_types,node_node_blockdefs,node_node_seed,node_node_utils toneAmber
class node_node_editor,node_node_editable_block,node_node_block_menu,node_node_slash_menu toneMint
class node_node_sidebar,node_node_topbar,node_node_pageheader,node_node_search,node_node_trash,node_node_icons toneRose
class node_node_github_workflow,node_node_smoke,node_node_shots toneIndigo
```

## Components

### App shell

Next.js entry points, global styling, and static export boundary

- [Layout](https://github.com/katsu996/notion/blob/main/app/layout.tsx): Next.js shell · Root app wrapper and global providers · `app/layout.tsx`
- [Workspace](https://github.com/katsu996/notion/blob/main/app/page.tsx): Next.js entry · Main page that mounts the app experience · `app/page.tsx`
- [Global CSS](https://github.com/katsu996/notion/blob/main/app/globals.css): styles · Base styling and responsive theme foundation · `app/globals.css`
- [Next config](https://github.com/katsu996/notion/blob/main/next.config.ts): build config · Static export and app build settings · `next.config.ts`

### State model

Shared document data, persistence, and seeded content

- [Store](https://github.com/katsu996/notion/blob/main/lib/store.tsx): react state · Central client-side state, persistence, and actions · `lib/store.tsx`
- [Types](https://github.com/katsu996/notion/blob/main/lib/types.ts): data model · Shared page and block document schema · `lib/types.ts`
- [Block defs](https://github.com/katsu996/notion/blob/main/lib/blockDefs.ts): block contract · Supported block types and editor behaviors · `lib/blockDefs.ts`
- [Seed data](https://github.com/katsu996/notion/blob/main/lib/seed.ts): initial content · Bootstrap content for first run or reset · `lib/seed.ts`
- [Utils](https://github.com/katsu996/notion/blob/main/lib/utils.ts): helpers · Shared utility functions · `lib/utils.ts`

### Editor

Block editing and document manipulation

- [Editor](https://github.com/katsu996/notion/blob/main/components/editor/Editor.tsx): block editor · Main document editor container · `components/editor/Editor.tsx`
- [Block item](https://github.com/katsu996/notion/blob/main/components/editor/EditableBlock.tsx): editable block · Per-block rendering and editing surface · `components/editor/EditableBlock.tsx`
- [Block menu](https://github.com/katsu996/notion/blob/main/components/editor/BlockMenu.tsx): block actions · Block-level commands and transforms · `components/editor/BlockMenu.tsx`
- [Slash menu](https://github.com/katsu996/notion/blob/main/components/editor/SlashMenu.tsx): command palette · Insert blocks via / commands · `components/editor/SlashMenu.tsx`

### Navigation

Workspace chrome, search, and page lifecycle UI

- [Sidebar](https://github.com/katsu996/notion/blob/main/components/Sidebar.tsx): page nav · Page tree, favorites, trash access, and mobile drawer · `components/Sidebar.tsx`
- [Topbar](https://github.com/katsu996/notion/blob/main/components/Topbar.tsx): workspace chrome · Top-level navigation and workspace controls · `components/Topbar.tsx`
- [Page header](https://github.com/katsu996/notion/blob/main/components/PageHeader.tsx): page chrome · Page title, icon, and cover presentation · `components/PageHeader.tsx`
- [Search](https://github.com/katsu996/notion/blob/main/components/SearchModal.tsx): global search · Modal for finding pages and content · `components/SearchModal.tsx`
- [Trash](https://github.com/katsu996/notion/blob/main/components/TrashPopover.tsx): page lifecycle · Restore and permanent delete actions · `components/TrashPopover.tsx`
- [Icons](https://github.com/katsu996/notion/blob/main/components/icons.tsx): icon set · Shared iconography for menus and chrome · `components/icons.tsx`

### Tooling

Build, deploy, and verification support

- [Deploy](https://github.com/katsu996/notion/blob/main/.github/workflows/deploy.yml): github pages · Static build and deployment workflow · `.github/workflows/deploy.yml`
- [Smoke test](https://github.com/katsu996/notion/blob/main/scripts/smoke-test.mjs): verification · Automated runtime sanity check · `scripts/smoke-test.mjs`
- [Screenshots](https://github.com/katsu996/notion/blob/main/scripts/screenshots.mjs): capture script · Visual capture for the static app · `scripts/screenshots.mjs`

## Connections

- 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
