Skip to content

Latest commit

 

History

History
245 lines (203 loc) · 11.2 KB

File metadata and controls

245 lines (203 loc) · 11.2 KB

DiffLab - Migration & Feature Plan

Migrating from single-file HTML to a Next.js app with multi-format comparison, local history, and polished UX.


Decisions (Resolved)

Question Decision Reasoning
Name DiffLab User preference. Existing "DiffLab" uses (AI co, image tool, research lab) don't overlap.
Deployment Vercel (Cloudflare Pages as fallback) App is mostly client-side. Vercel is native for Next.js. CF Pages works via static export.
Analytics Vercel Analytics Free on hobby plan, zero config on Vercel, ~1KB script, no cookies, GDPR-compliant.
Editor CodeMirror 6 Free (MIT), modular (~150KB base), performant. Monaco is ~2MB — overkill.
Local DB Dexie.js ~29KB gzip. Negligible vs CodeMirror + Next.js. Query-friendly API, good DX. Worth trying.
State mgmt Zustand (if needed) Only if prop drilling or cross-component state becomes a problem. Not preemptively.
Storage limit Browser-managed + soft warning at 80% No arbitrary cap. Warn user when approaching quota via navigator.storage.estimate().

Phase 0: Project Setup & Migration

  • Initialize Next.js project (App Router, TypeScript strict, Tailwind CSS v4, Bun)
  • Project structure: src/app, src/components, src/lib, src/hooks, src/stores, src/types
  • Configure ESLint, Prettier
  • Set up path aliases (@/)
  • Port existing JSON diff logic into src/lib/diff/
  • Port existing UI into React components
  • Remove Tailwind CDN, use proper Tailwind install
  • Verify feature parity with current single-file app before moving forward

Phase 1: Multi-Format Comparison Engine

Format Support

  • JSON (existing — port & improve)
  • YAML (yaml package)
  • TOML (smol-toml)
  • Plain text (line-by-line diff)
  • Markdown (line-by-line diff, treat as text)
  • Code files: JS, TS, Kotlin, Swift, etc. (line-by-line diff, treat as text)

Diff Strategies

  • Structured diff for JSON, YAML, TOML — parse into objects, compare keys/values (current behavior)
  • Text diff for everything else — line-by-line with diff (jsdiff) library
  • Unified diff view + side-by-side diff view toggle
  • Diff summary stats per format

Auto-Detection

  • Detect format from file extension on drop/upload
  • Detect format from content heuristics (leading {/[ = JSON, --- = YAML, [section] = TOML, etc.)
  • Format selector dropdown (manual override) per panel
  • Type mismatch error: if left panel is JSON and right panel is YAML, show clear error — do not compare
  • Allow "Text mode" override to force text diff regardless of format

Comparison Options

  • Ignore whitespace toggle (for text/code diffs)
  • Ignore case toggle
  • Ignore comments toggle (for code files — strip //, /* */, # before diff)

Phase 2: Editor & Syntax Highlighting

CodeMirror 6 Integration

  • Replace <textarea> with CodeMirror 6 editors
  • Language extensions: JSON, YAML, TOML, Markdown, JavaScript, TypeScript, Kotlin, Swift, HTML, CSS
  • Theme that matches app's dark/light mode (custom CodeMirror theme)
  • Line numbers
  • Code folding
  • Bracket matching
  • Search within editor (Ctrl+F)

Formatting

  • Format button per panel (pretty-print for structured formats, no-op for text)
  • JSON: JSON.stringify with indent
  • YAML: yaml.stringify with indent
  • TOML: smol-toml.stringify
  • Format on paste setting (toggle in settings/toolbar) — auto-format when content is pasted
  • Minify/compact button for structured formats
  • Preserve cursor position after format

Phase 3: Theme System (Light + Dark)

  • CSS custom properties for both themes (extend current --bg-base, --text, etc.)
  • Light theme color palette
  • Dark theme (current, refined)
  • System preference detection (prefers-color-scheme)
  • Manual toggle (dark / light / system) in navbar
  • Persist preference in localStorage
  • CodeMirror theme sync with app theme
  • Smooth transition between themes

Phase 4: Local Comparison History (IndexedDB via Dexie.js)

Storage Layer

  • Dexie.js setup with versioned schema
  • Schema: comparisons table with fields:
    • id (auto-generated UUID)
    • title (auto-generated or user-editable)
    • leftContent, rightContent
    • leftFormat, rightFormat
    • leftFileName, rightFileName
    • createdAt, updatedAt
    • tags (optional, for organization)
  • Storage quota monitoring via navigator.storage.estimate() — soft warning at 80%

History UI

  • History panel/page (/history)
  • List view: title, formats, date, preview snippet
  • Search/filter history by title, format, date range, tags
  • Sort by date (newest/oldest)
  • Load a saved comparison back into the editor
  • Edit comparison title/tags
  • Delete individual comparisons
  • Bulk delete / clear all (with confirmation)
  • Export history as JSON backup
  • Import history from JSON backup

Auto-Save

  • Option to auto-save comparisons (toggle in settings)
  • Save button to manually save current comparison
  • Indicator showing "saved" / "unsaved" state

Phase 5: SEO, Metadata & Analytics

Metadata

  • Dynamic <title> and <meta description> per page
  • Open Graph tags (og:title, og:description, og:image, og:url, og:type)
  • Twitter Card meta tags
  • Canonical URLs
  • Structured data (JSON-LD) for the tool

Assets

  • Favicon (SVG icon)
  • OG image (1200x630 branded preview card)
  • App icons for PWA manifest

SEO

  • robots.txt
  • sitemap.xml (generated via Next.js)
  • Proper heading hierarchy (h1, h2, etc.)
  • Semantic HTML throughout

Analytics (decide last — not a blocker)

Vercel Analytics Firebase/GA4 Clarity
Cost Free (2.5K events/mo) Free (unlimited) Free (unlimited)
Script size ~1KB ~45KB ~22KB
Cookies No Yes Yes
GDPR consent No Yes Yes
Setup 1 line Firebase project + SDK Script tag
Dashboard Simple, clean Complex, mobile-focused Heatmaps, recordings
Best for Web tools Mobile apps, funnels UX research
  • Pick analytics provider (Vercel Analytics recommended, decide at launch)
  • No tracking of content — only page views, referrers, basic usage

Phase 6: Sample Data & Onboarding

  • "Try an example" button/dropdown in toolbar or empty state
  • Sample pairs for every supported format:
    • JSON: two API responses with added/removed/changed fields
    • YAML: two config files (e.g., Kubernetes manifests) with diffs
    • TOML: two Cargo.toml or pyproject.toml files with version bumps
    • Markdown: two README versions with section changes
    • JavaScript/TypeScript: two versions of a function with refactoring
    • Kotlin: two data class versions
    • Swift: two struct versions
    • Plain text: two paragraphs with word changes
  • Clicking a sample auto-loads both panels, sets format, and runs diff
  • Samples stored as static assets in src/data/samples/ (not fetched from server)
  • Each sample has a short description shown in the dropdown
  • Empty state CTA: "Not sure how it works? Try an example" with a prominent button

Phase 7: Polish & UX

  • Keyboard shortcuts panel (help modal showing all shortcuts)
    • Ctrl+Shift+S swap (existing)
    • Ctrl+Shift+F format both
    • Ctrl+Shift+D toggle diff/keys view
    • Ctrl+S save comparison to history
    • ? toggle shortcuts modal
  • File upload button (not just drag & drop — some users prefer clicking)
  • File download button (formats structured data before download)
  • Inline filename editing (double-click to rename in editor header)
  • Ignore whitespace toggle for text diffs
  • Responsive design audit — mobile, tablet, desktop
  • Loading states, empty states, error states for all views
  • Toast notification system (improve existing)
  • Drag & drop refinements (visual feedback, multi-file handling)
  • Copy diff results (existing — extend for all formats)
  • Accessibility: ARIA labels, keyboard navigation, focus management, screen reader support
  • 404 page
  • Settings persistence (format on paste, ignore whitespace — persisted in localStorage)

Phase 8: Final Polish

  • Side-by-side diff view toggle (unified + split with toggle buttons)
  • Ignore case toggle for text diffs
  • Minify/compact button for structured formats (JSON, YAML, TOML)
  • Accessibility: ARIA labels, roles, aria-selected, aria-pressed, aria-modal on all interactive elements
  • Responsive design: flex-wrap toolbars, modal margins, label truncation

Deferred

  • Analytics integration (Vercel Analytics — decide at launch)
  • OG image (1200x630 branded preview card)
  • Auto-save toggle
  • Ignore comments toggle (strip //, /* */, # before diff)

Extras (Nice-to-Have, Post-Launch)

  • PWA: service worker, offline support, installable
  • Import from URL: fetch content from a remote URL into a panel
  • Share via link: encode small diffs in URL params or generate a temporary shareable hash (no server — URL encoding or free paste service)
  • Web Workers: offload diff computation for large files to a worker thread
  • Error recovery: auto-fix common JSON issues (trailing commas, single quotes, unquoted keys) with a "Try to fix" button
  • Diff navigation: jump to next/previous change in diff view
  • Collapsible sections in structured diff (collapse unchanged nested objects)
  • Character-level diff highlighting within changed lines (word diff)
  • Export diff: download diff as .patch, .txt, or .png (screenshot)
  • Duplicate detection (from original TODO)
  • Multiple tabs: concurrent comparisons in separate tabs within the app
  • Clipboard paste detection: auto-detect format from clipboard content on paste
  • Print-friendly styles for diff output

Tech Stack (Final)

Concern Choice
Framework Next.js 16 (App Router)
Language TypeScript (strict)
Runtime Bun
Styling Tailwind CSS v4
Editor CodeMirror 6
Diff engine jsdiff + custom structured
YAML parsing yaml
TOML parsing smol-toml
Local DB Dexie.js (~29KB gz)
State management Zustand (only if needed)
Analytics Vercel Analytics
Deployment Vercel (CF Pages as fallback)