A modern, AI-powered Markdown editor for crafting stunning README files — visually.
Write in rich text. Export pristine GitHub-Flavored Markdown. Let AI document your repos.
- Overview
- ✨ Features
- Rich Text Editor (WYSIWYG)
- Real-Time Markdown Conversion
- Live GitHub-Style Preview
- AI Documentation Agent
- Badge Studio
- Diagram Studio
- GitHub Profile Builder
- Templates Gallery
- Table of Contents Generator
- Emoji Picker
- GitHub Statistics Badges
- Image Insertion
- Document Outline & Navigation
- Import & Export
- Dark Mode
- Draft Persistence
- Authentication
- 🏗️ Architecture
- ⚙️ Tech Stack
- 🚀 Getting Started
- 📂 Project Structure
- 🔧 How It Works
- 📡 API Reference
- 🛣️ Roadmap
- 🤝 Contributing
- 📄 License
mdfmt (README Studio) is an open-source, browser-based Markdown editor purpose-built for crafting beautiful README files. It combines a rich-text WYSIWYG editor with real-time Markdown conversion, an AI-powered documentation agent, a badge studio, template gallery, and more — all in a polished, split-pane workspace.
Instead of memorizing Markdown syntax or toggling between a text editor and a preview, mdfmt gives you a visual editing experience: write naturally in a rich-text editor on the left, see the generated Markdown and a rendered GitHub-style preview on the right. Every keystroke produces clean, GitHub-Flavored Markdown in real time.
For existing projects, point the AI Agent at any public GitHub repository and it will analyze your codebase — cloning the repo, inspecting your tech stack, sampling source files, and generating comprehensive documentation powered by the Llama 3.3-70B model via Groq.
┌──────────────────────────────────────────────────────────────────────┐
│ ⌘ mdfmt Editor │ AI Agent │ Templates │ Badge Studio [🌙] │
├──────────────────────────────────────────────────────────────────────┤
│ Outline │ Import MD │ Clear Draft Copy Markdown │ Export│
├──────────────────────────────────────────────────────────────────────┤
│ H1 H2 H3 │ B I S ` │ • 1. ☐ │ ❝ — 🔗 📷 ▦ 🎯 😀 📊 ⚡ │ ↩ ↪ │
├─────────────────────────────────┬────────────────────────────────────┤
│ │ ┌─ Code ── Preview ─┐ 42 words │
│ │ │ │ │
│ WYSIWYG Rich-Text Editor │ │ # My Project │ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━ │ │ │ │
│ │ │ A modern web │ │
│ Write naturally here. │ │ application... │ │
│ Format with the toolbar │ │ │ │
│ or keyboard shortcuts. │ │ ## Features │ │
│ │ │ - Feature one │ │
│ │ │ - Feature two │ │
│ │ └────────────────────┘ │
└─────────────────────────────────┴────────────────────────────────────┘
Write naturally in a rich-text editor powered by TipTap and ProseMirror. No Markdown syntax to memorize — just click a toolbar button or use a keyboard shortcut.
| Category | Supported Elements |
|---|---|
| Headings | H1, H2, H3 with GitHub-style bottom borders |
| Inline Formatting | Bold, Italic, Inline Code |
| Lists | Bullet lists, Ordered lists, Task lists with checkboxes |
| Block Elements | Blockquotes, Horizontal rules, Fenced code blocks |
| Alert Blocks | Note 📝, Tip 💡, Important ❗, Warning |
| Links | Hyperlinks with URL prompt dialog |
| Images | Insert from URLs with alt text and live preview |
| Tables | 3×3 insertable tables with header rows, row/column management, and alignment controls |
| Snippets | Quick-insert pre-built content blocks |
Power user features:
- ⌨️ Keyboard shortcuts —
Ctrl+Bbold,Ctrl+Iitalic,Ctrl+Shift+Xstrikethrough, and more - 📋 Smart paste — paste HTML, Markdown, or plain text and it auto-converts
- ↩️ Undo/Redo — full history with toolbar buttons
- 🎯 Block selection — easily select and manipulate entire paragraphs or tables
- 🖱️ Drag & Drop — drop
.mdor.txtfiles directly into the editor
As you type, the output panel updates instantly. The conversion engine uses Turndown configured for GitHub-Flavored Markdown:
User types in Turndown converts Output panel
WYSIWYG Editor ──► HTML → Markdown ──► shows clean GFM
- ATX-style headings —
# Heading(not underline style) - Fenced code blocks — triple backticks with language tags
- Dash bullet markers —
- item(consistent style) - Strikethrough —
~~text~~via custom Turndown rule - Task lists —
- [x] Done/- [ ] Todo - Alert blocks —
> [!NOTE],> [!TIP],> [!IMPORTANT],> [!WARNING] - Table rendering — pipe-delimited format with proper alignment
- Image syntax —
via custom Turndown rule
Toggle between Code view (raw Markdown) and Preview view (rendered output) in the output pane. The preview uses react-markdown with remark-gfm and react-syntax-highlighter with the One Dark theme for syntax-highlighted code blocks — matching how your README will actually look on GitHub.
Live document metrics are displayed in the output header:
- 📝 Word count
- 📊 Character count
- ⏱️ Estimated reading time
Point the AI agent at any public GitHub repository and it generates comprehensive documentation automatically.
1. User provides 2. Backend clones 3. AI analyzes & 4. User reviews
GitHub repo URL ──► repo (depth=1) ──► generates docs ──► & revises
| Stage | What Happens |
|---|---|
| Repository Scraping | Shallow clone via git clone --depth 1, then walks the file tree (skipping node_modules, .git, dist, etc.) |
| File Sampling | Ranks files by importance (package.json, README, routes, schemas, components), reads up to 220 files / 260KB total |
| Tech Stack Detection | Identifies frameworks from package.json, Cargo.toml, go.mod, pyproject.toml, Dockerfile, and more |
| Analysis | Extracts dependencies, scripts, API routes, entry points, env vars, and project structure |
| Documentation Generation | Uses the Llama 3.3-70B model via Groq for AI-powered writing, or falls back to a local template engine |
| Depth | Output |
|---|---|
readme-only |
Quick, focused README with essential sections |
standard |
README + Architecture documentation |
complete |
README + Architecture + Development Guide + API Reference |
The generated documentation enters a review cycle:
queued → scraping → generating → needs_review → approved
↕
revising
- 📝 Provide feedback and the AI revises based on your suggestions
- ✅ Selectively approve individual files before committing
- 🔄 Iterate until your documentation is perfect
- 📊 Real-time job status tracking with async polling
Note: AI generation requires a Groq API key. Without one, the system falls back to intelligent template-based generation using heuristics from your repository structure.
A comprehensive badge creation and management system across a dedicated page:
| Category | Examples |
|---|---|
| Languages | Python, JavaScript, TypeScript, Go, Rust, Java, C++, C#, PHP, Ruby, Swift, Kotlin |
| Frameworks | React, Vue, Angular, Next.js, Svelte, Django, FastAPI, Spring, Flask, Express, NestJS |
| Tools & Platforms | Docker, Kubernetes, Git, GitHub, GitLab, VS Code, AWS, Firebase, MongoDB, PostgreSQL, Redis |
Quick-insert buttons organized by category — Languages (7), Frameworks (7), Tools (7) — for rapidly building a standardized tech stack display.
Create unlimited custom badges with shields.io integration:
- 🏷️ Label & Message — full text customization
- 🎨 Colors — 16+ preset colors or custom hex values
- 🖌️ Styles —
for-the-badge,flat,flat-square,plastic - 👁️ Live preview before inserting
- 📋 Copy-to-markdown — instant
generation
GitHub · Twitter/X · LinkedIn · YouTube · Discord · Reddit · Twitch · Instagram · Stack Overflow · Dev.to · Medium · Hashnode · Mastodon · Telegram · Email · Website
Automatically generates properly formatted badge links with batch insert support.
Translate your software architecture ideas into visual diagrams using AI and Mermaid.js!
- 🧠 AI Generation — Type out your database schema, user flow, or system architecture in plain English, and the LLaMA 3.3-70B model builds the Mermaid syntax.
- 👁️ Live Visualizer — See your diagram render perfectly within the UI, respecting both light and dark mode themes.
- 💻 Source Code Access — Inspect, tweak, and perfect the raw Mermaid code before inserting it.
- ⚡ One-Click Insert — Push the diagram code block straight into your editor draft.
Create an impressive user/user special GitHub profile README using our step-by-step wizard.
- 📝 Personal Info — Add your headline, bio, and personal details.
- 🔗 Social Links — Instantly link your Twitter, LinkedIn, GitHub, and Portfolio.
- 🛠️ Tech Stack Grid — Click to select from popular technologies and auto-generate beautifully aligned badges.
- 📊 Dynamic GitHub Stats — Integrate
github-readme-statscards, top languages, and apply beautiful custom themes (Radical, Tokyo Night, Dracula, etc.) instantly. - 👁️ Live Preview — See the compiled markdown output in real time.
Pre-built README templates to jumpstart your documentation:
| Template | Use Case |
|---|---|
| Minimalist Project | Clean, lightweight template for small projects |
| Comprehensive Library | Full-featured template for open-source libraries |
| API Reference Server | Specialized template for API documentation |
| Portfolio Project | Template designed for personal portfolio showcases |
Each template includes pre-structured sections (Overview, Installation, Usage, Contributing, License), properly formatted headings and code blocks, and is fully editable in the WYSIWYG editor.
Automatically generate a clickable table of contents from your document:
- 🔍 Auto-scans all H1, H2, and H3 headings from the editor content
- 🔗 Generates GitHub-compatible anchor links (slugified, lowercase, hyphenated)
- 🔄 Dynamic updates — regenerate as you add or modify headings
- 📍 Customizable placement — insert anywhere in your document
Browse and insert emojis organized by 7 categories:
| Category | Examples |
|---|---|
| Smileys & People | 😀 😂 🤔 👍 |
| Animals & Nature | 🐱 🌿 🌸 🦋 |
| Food & Drink | 🍕 ☕ 🍰 🍎 |
| Travel & Places | |
| Activities & Sports | ⚽ 🎮 🎨 🏆 |
| Objects | 💻 📱 🔧 📦 |
| Symbols | ❤️ ⭐ ✅ ⚡ |
Insert dynamic badges that display live information from any GitHub repository:
- ⭐ Stars — repository star count
- 🍴 Forks — number of forks
- 👀 Watchers — active watchers
- 🐛 Issues — open issue count
- 📜 License — detected license type
- 📅 Last Commit — most recent commit date
These badges auto-update as your repository grows, always showing fresh metrics.
Seamlessly add images to your README from URLs:
- 👁️ Live preview — see images before inserting
- 📝 Alt text support — accessibility and SEO
- ✅ URL validation — ensures images load properly
- 📄 Markdown-compatible — generates
syntax
A collapsible outline panel on the left side of the editor:
- 🗂️ Automatically detects all headings (H1–H6) from the editor
- 🏷️ Shows heading level indicators (H1, H2, H3)
- 🖱️ Click any heading to smooth-scroll to it with a highlight animation
- 📐 Indented hierarchy matching your document structure
- 🔄 Real-time updates as you type
| Action | Details |
|---|---|
| Import .md | Upload existing Markdown files via file picker — auto-parsed into the WYSIWYG editor |
| Drag & Drop | Drop .md or .txt files directly into the editor area |
| Export .md | Download as README.md — client-side via the Blob API, no server needed |
| Export .html | Download the raw HTML representation |
| Copy Markdown | One-click copy to clipboard with a 2-second "Copied!" confirmation |
Toggle between light and dark themes with a single click:
- 🌓 Full application coverage — editor, toolbar, output pane, modals, all pages
- 💾 Persistent state — remembered across sessions via Zustand
- ✨ Smooth CSS transitions when switching
- 🎨 Tailwind CSS
classstrategy for efficient dark mode styling
Your work is automatically saved to localStorage:
- Every keystroke persists both the Markdown and HTML to local storage
- Drafts survive browser refreshes, tab closes, and crashes
- "Clear Draft" button with confirmation dialog to start fresh
- Templates and AI-generated content automatically populate the draft store
Complete user authentication system (pages built, Firebase integration ready):
- 📧 Email & Password — traditional account creation with password strength indicator (Too Short → Fair → Good → Strong)
- 🔵 Google OAuth — one-click sign-in
- 🐙 GitHub OAuth — authenticate with your GitHub account
- 🔥 Firebase Integration — secure, reliable auth backend
- 💾 Persistent Sessions — stay logged in across browser sessions via
onAuthStateChanged
mdfmt is a monorepo with two independent services:
┌─────────────────────────────────────────────────────────────────────┐
│ mdfmt Monorepo │
├──────────────────────────────┬──────────────────────────────────────┤
│ frontend/ │ backend/ │
│ React 19 + Vite 7 │ Express 5 + Node.js │
│ │ │
│ ┌────────────────────────┐ │ ┌────────────────────────────────┐ │
│ │ Pages │ │ │ REST API │ │
│ │ ├── EditorPage │ │ │ └── /api/build-ai │ │
│ │ ├── AiGeneratorPage │ │ │ ├── POST /jobs │ │
│ │ ├── BadgeStudioPage │ │ │ ├── POST /generate │ │
│ │ ├── DiagramStudioPage│ │ │ ├── GET /jobs/:id │ │
│ │ ├── ProfileBuilderPage│ │ │ ├── POST /jobs/:id/revise│ │
│ │ ├── TemplatesPage │ │ │ ├── POST /jobs/:id/approve││
│ │ ├── SignInPage │ │ │ └── POST /diagram │ │
│ │ └── SignUpPage │ │ │ │ │
│ └────────────────────────┘ │ └────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┐ │ ┌────────────────────────────────┐ │
│ │ Components (14) │ │ │ Services │ │
│ │ ├── Toolbar │ │ │ ├── githubService (clone) │ │
│ │ ├── TableToolbar │ │ │ ├── aiService (generate) │ │
│ │ ├── Navbar │ │ │ ├── llmService (Groq) │ │
│ │ ├── AlertBlockDD │ │ │ └── jobStore (in-mem) │ │
│ │ ├── AutoTocButton │ │ └────────────────────────────────┘ │
│ │ ├── BadgePickerModal│ │ │
│ │ ├── CustomBadgeModal│ │ ┌────────────────────────────────┐ │
│ │ ├── EmojiPickerModal│ │ │ Utils │ │
│ │ ├── GitHubStatsModal│ │ │ ├── asyncHandler │ │
│ │ ├── InsertImageModal│ │ │ └── httpErrors │ │
│ │ ├── SnippetDropdown │ │ └────────────────────────────────┘ │
│ │ ├── SocialLinksModal│ │ │
│ │ ├── TechStackGrid │ │ │
│ │ └── TemplatesSidebar│ │ │
│ └────────────────────────┘ │ │
│ │ │
│ ┌────────────────────────┐ │ │
│ │ State (Zustand) │ │ │
│ │ ├── useThemeStore │ │ │
│ │ ├── useDraftStore │ │ │
│ │ └── useAuthStore │ │ │
│ └────────────────────────┘ │ │
│ │ │
│ ┌────────────────────────┐ │ │
│ │ Libs │ │ │
│ │ ├── firebase.ts │ │ │
│ │ └── markdownParser │ │ │
│ └────────────────────────┘ │ │
├──────────────────────────────┴──────────────────────────────────────┤
│ Shared: TypeScript 5.9 │
└─────────────────────────────────────────────────────────────────────┘
The core editor follows a unidirectional data flow:
┌──────────────────┐ HTML ┌──────────────────┐ Markdown ┌──────────────────┐
│ │ ──────────► │ │ ──────────── ► │ │
│ TipTap Editor │ onUpdate │ Turndown │ setState │ Output Panel │
│ (ProseMirror) │ │ (HTML → GFM) │ │ (Code/Preview) │
│ │ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ │
│ ┌──────────────────┐ │
└──────────────── ► │ Zustand Store │ ◄ ────────────────────────┘
persist HTML │ (useDraftStore) │ persist Markdown
│ + localStorage │
└──────────────────┘
- User types in the TipTap WYSIWYG editor, which internally maintains a ProseMirror document
- On every keystroke (
onUpdate), TipTap emits the current document as HTML - HTML is piped through Turndown (configured for GFM) to produce clean Markdown
- Both HTML and Markdown are persisted to the Zustand draft store (backed by
localStorage) - The output panel renders either the raw Markdown or a GitHub-style preview
┌────────────┐ POST ┌────────────────┐ git clone ┌────────────────┐
│ │ /api/build-ai │ │ --depth 1 │ │
│ Frontend │ ────────────► │ Express API │ ──────────── ► │ GitHub │
│ AI Agent │ │ (Job Queue) │ │ Repository │
│ Page │ ◄──────────── │ │ ◄──────────────│ │
│ │ Job Status │ │ File Tree │ │
└────────────┘ Polling └───────┬────────┘ + Contents └────────────────┘
│
┌───────▼────────┐
│ AI Service │
│ │
│ ┌───────────┐ │
│ │ Groq LLM │ │ ◄── Llama 3.3-70B
│ │ (primary) │ │
│ └───────────┘ │
│ OR │
│ ┌───────────┐ │
│ │ Template │ │ ◄── Heuristic fallback
│ │ Engine │ │
│ └───────────┘ │
└────────────────┘
| Requirement | Version |
|---|---|
| Node.js | ≥ 18 |
| npm | ≥ 9 (or yarn / pnpm) |
| Git | Required on the server for the AI agent's repository cloning |
# 1. Clone the repository
git clone https://github.com/ApurveKaranwal/mdfmt.git
cd mdfmt
# 2. Install frontend dependencies
cd frontend
npm install
# 3. (Optional) Configure Firebase for authentication
cp .env.example .env
# Fill in your Firebase credentials — see Environment Variables below
# 4. Start the dev server
npm run devThe dev server starts at http://localhost:5173 with Vite's hot module replacement enabled.
# 1. Navigate to backend
cd backend
npm install
# 2. Configure environment
cp .env.example .env
# Set your Groq API key and other options — see Environment Variables below
# 3. Start the dev server
npm run devThe backend API starts at http://localhost:4000.
| Variable | Required | Description |
|---|---|---|
VITE_FIREBASE_API_KEY |
Optional | Firebase API key |
VITE_FIREBASE_AUTH_DOMAIN |
Optional | Firebase auth domain |
VITE_FIREBASE_PROJECT_ID |
Optional | Firebase project ID |
VITE_FIREBASE_STORAGE_BUCKET |
Optional | Firebase storage bucket |
VITE_FIREBASE_MESSAGING_SENDER_ID |
Optional | Firebase messaging sender ID |
VITE_FIREBASE_APP_ID |
Optional | Firebase app ID |
Note: Firebase variables are optional. The editor works fully without them — authentication features are simply disabled.
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 4000 |
Server port |
FRONTEND_ORIGIN |
No | http://localhost:5173 |
CORS allowed origin |
GITHUB_TOKEN |
No | — | Improves clone access for private repos / rate-limited environments |
GROQ_MODEL |
No | llama-3.3-70b-versatile |
LLM model for AI generation |
MAX_REPO_FILES |
No | 220 |
Max files to sample per repository |
MAX_REPO_BYTES |
No | 260000 |
Max total bytes to read from a repo |
MAX_FILE_BYTES |
No | 12000 |
Max bytes per individual file |
cd frontend
npm run build # Type-check with tsc, then bundle with Vite
npm run preview # Preview the production build locallyProduction assets are output to frontend/dist/.
mdfmt/
├── 📄 LICENSE # MIT License
├── 📄 README.md # This file
├── 📄 .gitignore # Global gitignore
│
├── 🎨 frontend/ # React + Vite + TailwindCSS
│ ├── 📄 index.html # HTML entry point
│ ├── 📄 package.json # Dependencies & scripts
│ ├── 📄 vite.config.ts # Vite configuration
│ ├── 📄 tailwind.config.js # Tailwind (class-based dark mode)
│ ├── 📄 postcss.config.js # PostCSS (Tailwind + Autoprefixer)
│ ├── 📄 tsconfig.json # TypeScript project references
│ ├── 📄 tsconfig.app.json # App-level TS config
│ ├── 📄 tsconfig.node.json # Node-level TS config (Vite)
│ ├── 📄 eslint.config.js # ESLint flat config
│ ├── 📄 .env.example # Firebase env template
│ ├── 📁 public/ # Static assets
│ │ └── vite.svg
│ └── 📁 src/
│ ├── 📄 main.tsx # Entry — mounts React with BrowserRouter
│ ├── 📄 App.tsx # Root — defines 4 routes
│ ├── 📄 index.css # Global + TipTap editor styles (8KB)
│ │
│ ├── 📁 pages/
│ │ ├── 📄 EditorPage.tsx # Main WYSIWYG editor + split preview
│ │ ├── 📄 AiGeneratorPage.tsx # AI documentation generator UI
│ │ ├── 📄 BadgeStudioPage.tsx # Badge creation & management
│ │ ├── 📄 DiagramStudioPage.tsx # Mermaid.js AI generation
│ │ ├── 📄 ProfileBuilderPage.tsx # GitHub profile builder wizard
│ │ ├── 📄 TemplatesPage.tsx # Pre-built README templates
│ │ ├── 📄 SignInPage.tsx # Sign in (Email + OAuth)
│ │ └── 📄 SignUpPage.tsx # Sign up with password strength
│ │
│ ├── 📁 components/
│ │ ├── 📄 Navbar.tsx # Top navigation bar
│ │ ├── 📄 Toolbar.tsx # Editor formatting toolbar
│ │ ├── 📄 TableToolbar.tsx # Table-specific actions
│ │ ├── 📄 AlertBlockDropdown.tsx # Alert block type picker
│ │ ├── 📄 AutoTocButton.tsx # Table of contents generator
│ │ ├── 📄 SnippetDropdown.tsx # Quick-insert snippets
│ │ ├── 📄 EmojiPickerModal.tsx # Emoji browser (7 categories)
│ │ ├── 📄 InsertImageModal.tsx # Image URL insertion
│ │ ├── 📄 BadgePickerModal.tsx # Pre-built badge library
│ │ ├── 📄 CustomBadgeModal.tsx # Custom badge builder
│ │ ├── 📄 GitHubStatsModal.tsx # GitHub repo stats badges
│ │ ├── 📄 SocialLinksModal.tsx # Social media link badges
│ │ ├── 📄 TechStackGrid.tsx # Quick tech stack grid
│ │ └── 📄 TemplatesSidebar.tsx # Template browser sidebar
│ │
│ ├── 📁 store/
│ │ ├── 📄 useThemeStore.ts # Dark mode state (Zustand)
│ │ ├── 📄 useDraftStore.ts # Editor draft persistence (Zustand + localStorage)
│ │ └── 📄 useAuthStore.ts # Auth state + Firebase listener (Zustand)
│ │
│ └── 📁 lib/
│ ├── 📄 firebase.ts # Firebase init + auth helpers
│ └── 📄 markdownParser.ts # MD → HTML parser for imports
│
└── ⚙️ backend/ # Express + TypeScript API
├── 📄 package.json # Dependencies & scripts
├── 📄 tsconfig.json # TypeScript configuration
├── 📄 .env.example # Backend env template
└── 📁 src/
├── 📄 server.ts # Express app + middleware + error handling
├── 📄 config.ts # Environment variable configuration
├── 📄 types.ts # Shared TypeScript interfaces
│
├── 📁 routes/
│ └── 📄 buildAiRoutes.ts # AI documentation REST endpoints
│
├── 📁 services/
│ ├── 📄 aiService.ts # Documentation generation engine (857 lines)
│ ├── 📄 githubService.ts # Repository cloning & file analysis
│ ├── 📄 llmService.ts # Groq API integration
│ └── 📄 jobStore.ts # In-memory job queue
│
└── 📁 utils/
├── 📄 asyncHandler.ts # Express async error wrapper
└── 📄 httpErrors.ts # Custom HTTP error class
The WYSIWYG editor is built on TipTap, a headless, framework-agnostic rich-text editor built on ProseMirror. The following extensions are loaded:
| Extension | Purpose |
|---|---|
StarterKit |
Core nodes (paragraph, heading, code block, blockquote, lists, horizontal rule) and marks (bold, italic, strike, code) |
Link |
Hyperlink support with openOnClick: false to prevent accidental navigation |
Image |
Inline image insertion with base64 support |
TaskList + TaskItem |
GitHub-style task lists with interactive checkboxes and nesting |
Table + TableRow + TableHeader + TableCell |
Full table support with resizable columns |
Turndown converts TipTap's HTML output into clean Markdown:
const turndownService = new TurndownService({
headingStyle: 'atx', // # Heading (not underline)
codeBlockStyle: 'fenced', // ``` blocks (not indentation)
bulletListMarker: '-', // - item (not * or +)
});
// Custom rule: <del>/<s> tags → ~~strikethrough~~
turndownService.addRule('strikethrough', {
filter: ['del', 's'],
replacement: (content) => `~~${content}~~`,
});
// Custom rule: <img> → 
turndownService.addRule('image', {
filter: 'img',
replacement: (_content, node) => {
const el = node as HTMLElement;
return ` || ''})`;
},
});When importing .md files, a custom parser (markdownParser.ts) converts Markdown back to HTML for the TipTap editor. It handles:
- Fenced code blocks with language tags
- Inline code
- Headings (H1–H6)
- Images and links
- Blockquotes and alert blocks
- Unordered and ordered lists
- Paragraph wrapping with
<br />for line breaks
Three Zustand stores manage global state:
| Store | State | Persistence |
|---|---|---|
useThemeStore |
isDarkMode, toggleDarkMode() |
Toggles dark class on document.documentElement |
useDraftStore |
markdown, htmlContent, setMarkdown(), setHtmlContent(), clearDraft() |
localStorage (mdfmt_md_draft, mdfmt_html_draft) |
useAuthStore |
user, loading, setUser(), setLoading() |
Firebase onAuthStateChanged listener |
The githubService performs intelligent repository analysis:
- Shallow clone —
git clone --depth 1into a temp directory (supports authenticated clones viaGITHUB_TOKEN) - File tree walk — recursively lists all files, skipping ignored directories (
node_modules,.git,dist,build,__pycache__,vendor, etc.) - Priority ranking — files are scored by importance:
package.json,README.md,Cargo.toml,go.mod→ +20 points- Routes, controllers, services, schemas → +8 points
- Test files → +4 points
- Markdown files → +10 points
- Content sampling — reads up to 220 files / 260KB total, truncating individual files at 12KB
- Tech stack detection — identifies Node.js, Vite, Tailwind, Next.js, React, Express, Python, Go, Rust, Docker, Firebase, Prisma, and more from manifests and file paths
- Cleanup — temporary clone directory is always deleted (
rm -rfinfinallyblock)
The aiService supports two generation modes:
LLM-Powered (Groq):
- Uses the Llama 3.3-70B model with temperature 0.45 for README, 0.5 for architecture docs
- Builds a focused context from repository metadata, dependencies, scripts, API routes, and sampled source files
- Token-efficient chunked context strategy to stay within limits
- Revision mode with temperature 0.35 for precise, feedback-driven edits
Template-Based Fallback:
- Activated when no Groq API key is provided
- Generates structured README from detected badges, tech stack, feature bullets, file tree, prerequisites, scripts, API routes, and configuration
- Produces architecture and development guide templates from repository analysis
- Includes intelligent "creator questions" for missing information
All endpoints are prefixed with /api/build-ai.
| Method | Endpoint | Description |
|---|---|---|
POST |
/jobs |
Create a new documentation generation job (async, returns immediately) |
POST |
/generate |
Create and wait for a documentation generation job (sync) |
GET |
/jobs/:jobId |
Get the current status and result of a job |
POST |
/jobs/:jobId/revise |
Submit feedback to revise generated documentation |
POST |
/jobs/:jobId/approve |
Approve generated files (optionally selective via approvedPaths) |
GET |
/health |
Health check endpoint |
{
"projectName": "My Project",
"githubUrl": "https://github.com/owner/repo",
"groqApiKey": "gsk_...",
"instructions": "Focus on the API documentation...",
"documentationDepth": "standard"
}| Field | Type | Required | Description |
|---|---|---|---|
projectName |
string | ✅ | Title for the generated documentation (max 120 chars) |
githubUrl |
string | ✅ | GitHub repository URL to analyze |
groqApiKey |
string | ✅ | Groq API key for LLM-powered generation |
instructions |
string | ❌ | Custom instructions for the AI (max 4000 chars) |
documentationDepth |
string | ❌ | readme-only | standard | complete (default: standard) |
queued → scraping → generating → needs_review → approved
↕
revising
* Any stage can transition to → failed
| Feature | Description |
|---|---|
| Cloud Persistence | Save README files to a database via Prisma ORM for cross-device access |
| Live Markdown Preview | Rendered GitHub-style preview as a third pane option |
| Code Block Language Selector | Dropdown to specify language for fenced code blocks |
| Feature | Description |
|---|---|
| Collaborative Editing | Real-time collaboration via WebSockets + Yjs (TipTap supports it natively) |
| GitHub Push Integration | Push generated README directly to a repository via the GitHub API |
| Responsive / Mobile Layout | Stack panes vertically on smaller screens |
| Keyboard Shortcuts Panel | Help modal listing all available shortcuts |
| Syntax Highlighting in Editor | Code highlighting via @tiptap/extension-code-block-lowlight |
| Feature | Description |
|---|---|
| Export to PDF / RST | Additional export formats beyond .md and .html |
| Version History | Track changes over time with revert capability |
| Custom Themes | Font selection, accent colors, and theme customization |
| Drag-and-Drop Reordering | Reorder document sections via drag-and-drop |
| Script | Command | Description |
|---|---|---|
| Dev | npm run dev |
Start Vite dev server with HMR at :5173 |
| Build | npm run build |
Type-check with tsc -b then bundle for production |
| Preview | npm run preview |
Serve the production build locally |
| Lint | npm run lint |
Run ESLint on all source files |
| Script | Command | Description |
|---|---|---|
| Dev | npm run dev |
Start with Nodemon + ts-node (auto-restart on changes) |
| Build | npm run build |
Compile TypeScript to dist/ |
| Start | npm start |
Run the compiled production build |
| Typecheck | npm run typecheck |
Run tsc --noEmit for type validation |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch
git checkout -b feature/my-feature
- Commit your changes
git commit -m "feat: add my feature" - Push to the branch
git push origin feature/my-feature
- Open a Pull Request
Please ensure your code:
- ✅ Passes linting —
npm run lint - ✅ Builds successfully —
npm run build - ✅ Follows existing code style and TypeScript conventions
This project is licensed under the MIT License — see the LICENSE file for details.
MIT License
Copyright (c) 2026 Apurve Karanwal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software...
Built by Apurve Karanwal