# pennypenny135-coder/excel-mail-merge architecture

> Architecture diagram of the GitHub repository pennypenny135-coder/excel-mail-merge, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-15). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pennypenny135-coder/excel-mail-merge
- Repository: https://github.com/pennypenny135-coder/excel-mail-merge

## Overview

Excel Mail Merge Studio is a browser-only application for turning XLSX rows into formatted DOCX files. Users load and inspect a workbook, create or edit a template, bind placeholders to columns, choose rows, review validation and previews, then generate and download documents. Templates, folders, preferences, and limited workbook metadata persist in IndexedDB; workbook contents and generated files stay in the browser. The graph follows documented product flows and sampled imports/calls; unsampled implementation detail is omitted where relationships cannot be verified.

Main entry points: [`src/components/app-shell.tsx`](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-shell.tsx) (App navigation), [`src/components/merge/merge-view.tsx`](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/merge/merge-view.tsx) (Merge workspace), [`src/components/app-context.tsx`](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-context.tsx) (App state), [`src/hooks/useMailMerge.ts`](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useMailMerge.ts) (Generation workflow)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application and templates"]
  node_shell["App navigation<br/>[app-shell.tsx]"]
  node_context["App state<br/>[app-context.tsx]"]
  node_dashboard["Dashboard<br/>[dashboard-view.tsx]"]
  node_templates["Template manager<br/>[templates-view.tsx]"]
  node_editor["Rich editor"]
  node_template_model["Template model<br/>[template.ts]"]
  node_transfer_ui["Import/export UI<br/>[import-dialog.tsx]"]
  node_transfer["Template transfer<br/>[transfer.ts]"]
  node_settings["Settings<br/>[settings-view.tsx]"]
end

subgraph group_excel["Excel data"]
  node_excel_ui["Workbook view<br/>[excel-view.tsx]"]
  node_dropzone["Excel dropzone<br/>[excel-dropzone.tsx]"]
  node_excel_hook["Workbook state<br/>[useExcel.ts]"]
  node_excel_parser["XLSX parsing<br/>[excel.ts]"]
end

subgraph group_merge["Merge and output"]
  node_merge_ui["Merge workspace<br/>[merge-view.tsx]"]
  node_preview["Merge preview<br/>[preview.tsx]"]
  node_validation["Merge validation<br/>[validation.ts]"]
  node_merge_hook["Generation workflow<br/>[useMailMerge.ts]"]
  node_merge_logic["Row merge<br/>[merge.ts]"]
  node_formatting["Value formatting<br/>[formatting.ts]"]
  node_docx["DOCX generation<br/>[docx.ts]"]
  node_downloads["Browser downloads<br/>[useMailMerge.ts]"]
end

subgraph group_local["Local persistence"]
  node_storage[("IndexedDB storage<br/>[storage.ts]")]
  node_template_hook["Template state<br/>[useTemplates.ts]"]
end

node_user(("User"))

node_user -->|"uses"| node_shell
node_shell -->|"routes to"| node_dashboard
node_shell -->|"routes to"| node_excel_ui
node_shell -->|"routes to"| node_templates
node_shell -->|"routes to"| node_merge_ui
node_shell -->|"routes to"| node_settings
node_shell -->|"routes to"| node_editor
node_dashboard -->|"renders"| node_dropzone
node_excel_ui -->|"renders"| node_dropzone
node_context -->|"creates"| node_excel_hook
node_excel_hook -->|"uses"| node_excel_parser
node_excel_ui -->|"uses"| node_excel_parser
node_user -->|"uploads workbook"| node_excel_ui
node_user -->|"creates template"| node_templates
node_templates -->|"opens import/export"| node_transfer_ui
node_transfer_ui -->|"uses"| node_transfer
node_settings -->|"opens import/export"| node_transfer_ui
node_context -->|"manages templates"| node_template_hook
node_context -->|"creates templates"| node_template_model
node_editor -->|"edits template"| node_templates
node_merge_ui -->|"renders"| node_preview
node_merge_ui -->|"validates"| node_validation
node_merge_ui -->|"uses"| node_merge_hook
node_merge_ui -->|"uses"| node_merge_logic
node_preview -->|"uses"| node_merge_logic
node_preview -->|"formats values"| node_formatting
node_merge_hook -->|"merges rows"| node_merge_logic
node_merge_hook -->|"builds documents"| node_docx
node_merge_logic -->|"formats placeholders"| node_formatting
node_merge_hook -->|"downloads results"| node_downloads
node_user -->|"selects and generates"| node_merge_ui
node_template_hook -->|"reads and writes"| node_storage
node_context -->|"loads preferences"| node_storage
node_settings -->|"updates preferences"| node_context

click node_shell "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-shell.tsx"
click node_context "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-context.tsx"
click node_dashboard "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/dashboard/dashboard-view.tsx"
click node_templates "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/templates/templates-view.tsx"
click node_editor "https://github.com/pennypenny135-coder/excel-mail-merge/tree/main/src/components/editor"
click node_template_model "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/template.ts"
click node_transfer_ui "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/templates/import-dialog.tsx"
click node_transfer "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/transfer.ts"
click node_settings "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/settings/settings-view.tsx"
click node_excel_ui "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/excel/excel-view.tsx"
click node_dropzone "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/excel/excel-dropzone.tsx"
click node_excel_hook "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useExcel.ts"
click node_excel_parser "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/excel.ts"
click node_merge_ui "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/merge/merge-view.tsx"
click node_preview "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/merge/preview.tsx"
click node_validation "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/validation.ts"
click node_merge_hook "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useMailMerge.ts"
click node_merge_logic "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/merge.ts"
click node_formatting "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/formatting.ts"
click node_docx "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/docx.ts"
click node_downloads "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useMailMerge.ts"
click node_storage "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/storage.ts"
click node_template_hook "https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useTemplates.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_shell,node_context,node_dashboard,node_templates,node_editor,node_template_model,node_transfer_ui,node_transfer,node_settings,node_user toneBlue
class node_excel_ui,node_dropzone,node_excel_hook,node_excel_parser toneAmber
class node_merge_ui,node_preview,node_validation,node_merge_hook,node_merge_logic,node_formatting,node_docx,node_downloads toneMint
class node_storage,node_template_hook toneRose
```

## Components

### Application and templates

- [App navigation](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-shell.tsx): `src/components/app-shell.tsx`
- [App state](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/app-context.tsx): `src/components/app-context.tsx`
- [Dashboard](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/dashboard/dashboard-view.tsx): `src/components/dashboard/dashboard-view.tsx`
- [Template manager](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/templates/templates-view.tsx): `src/components/templates/templates-view.tsx`
- [Rich editor](https://github.com/pennypenny135-coder/excel-mail-merge/tree/main/src/components/editor): `src/components/editor`
- [Template model](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/template.ts): `src/lib/template.ts`
- [Import/export UI](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/templates/import-dialog.tsx): `src/components/templates/import-dialog.tsx`
- [Template transfer](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/transfer.ts): `src/lib/transfer.ts`
- [Settings](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/settings/settings-view.tsx): `src/components/settings/settings-view.tsx`

### Excel data

- [Workbook view](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/excel/excel-view.tsx): `src/components/excel/excel-view.tsx`
- [Excel dropzone](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/excel/excel-dropzone.tsx): `src/components/excel/excel-dropzone.tsx`
- [Workbook state](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useExcel.ts): `src/hooks/useExcel.ts`
- [XLSX parsing](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/excel.ts): `src/lib/excel.ts`

### Merge and output

- [Merge workspace](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/merge/merge-view.tsx): `src/components/merge/merge-view.tsx`
- [Merge preview](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/components/merge/preview.tsx): `src/components/merge/preview.tsx`
- [Merge validation](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/validation.ts): `src/lib/validation.ts`
- [Generation workflow](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useMailMerge.ts): `src/hooks/useMailMerge.ts`
- [Row merge](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/merge.ts): `src/lib/merge.ts`
- [Value formatting](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/formatting.ts): `src/lib/formatting.ts`
- [DOCX generation](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/docx.ts): `src/lib/docx.ts`
- [Browser downloads](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useMailMerge.ts): `src/hooks/useMailMerge.ts`

### Local persistence

- [IndexedDB storage](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/lib/storage.ts): `src/lib/storage.ts`
- [Template state](https://github.com/pennypenny135-coder/excel-mail-merge/blob/main/src/hooks/useTemplates.ts): `src/hooks/useTemplates.ts`

### Other components

- **User**

## Connections

- User → App navigation: uses
- App navigation → Dashboard: routes to (evidence: `src/components/app-shell.tsx`)
- App navigation → Workbook view: routes to (evidence: `src/components/app-shell.tsx`)
- App navigation → Template manager: routes to (evidence: `src/components/app-shell.tsx`)
- App navigation → Merge workspace: routes to (evidence: `src/components/app-shell.tsx`)
- App navigation → Settings: routes to (evidence: `src/components/app-shell.tsx`)
- App navigation → Rich editor: routes to (evidence: `src/components/app-shell.tsx`)
- Dashboard → Excel dropzone: renders (evidence: `src/components/dashboard/dashboard-view.tsx`)
- Workbook view → Excel dropzone: renders (evidence: `src/components/excel/excel-view.tsx`)
- App state → Workbook state: creates (evidence: `src/components/app-context.tsx`)
- Workbook state → XLSX parsing: uses (evidence: `src/hooks/useExcel.ts`)
- Workbook view → XLSX parsing: uses (evidence: `src/components/excel/excel-view.tsx`)
- User → Workbook view: uploads workbook
- User → Template manager: creates template
- Template manager → Import/export UI: opens import/export (evidence: `src/components/templates/templates-view.tsx`)
- Import/export UI → Template transfer: uses (evidence: `src/components/templates/import-dialog.tsx`)
- Settings → Import/export UI: opens import/export (evidence: `src/components/settings/settings-view.tsx`)
- App state → Template state: manages templates (evidence: `src/components/app-context.tsx`)
- App state → Template model: creates templates (evidence: `src/components/app-context.tsx`)
- Rich editor → Template manager: edits template
- Merge workspace → Merge preview: renders (evidence: `src/components/merge/merge-view.tsx`)
- Merge workspace → Merge validation: validates (evidence: `src/components/merge/merge-view.tsx`)
- Merge workspace → Generation workflow: uses (evidence: `src/components/merge/merge-view.tsx`)
- Merge workspace → Row merge: uses (evidence: `src/components/merge/merge-view.tsx`)
- Merge preview → Row merge: uses (evidence: `src/components/merge/preview.tsx`)
- Merge preview → Value formatting: formats values (evidence: `src/components/merge/preview.tsx`)
- Generation workflow → Row merge: merges rows (evidence: `src/hooks/useMailMerge.ts`)
- Generation workflow → DOCX generation: builds documents (evidence: `src/hooks/useMailMerge.ts`)
- Row merge → Value formatting: formats placeholders (evidence: `src/lib/merge.ts`)
- Generation workflow → Browser downloads: downloads results (evidence: `src/hooks/useMailMerge.ts`)
- User → Merge workspace: selects and generates
- Template state → IndexedDB storage: reads and writes (evidence: `src/hooks/useTemplates.ts`)
- App state → IndexedDB storage: loads preferences (evidence: `src/components/app-context.tsx`)
- Settings → App state: updates preferences (evidence: `src/components/settings/settings-view.tsx`)
