Why Vite + React (Not Next.js)
This is a tool, not a content site. There's no SEO-critical dynamic content, no server-side rendering needed, no API routes for data fetching. Everything happens client-side: the QR code is generated in a canvas, styled with options, and downloaded as a blob.
Vite gives sub-second hot reload during development and produces optimized static bundles. The entire app ships as a single index.html with hashed JS/CSS chunks. Vercel serves it from a CDN edge. Cold load to interactive is under 2 seconds on average connections.
Next.js would add SSR/RSC complexity for zero benefit here. A framework should match the problem. This problem is 'render a canvas in the browser fast.'
Why qr-code-styling (Not qrcode.js)
Most QR libraries give you a black-and-white grid and call it a day. qr-code-styling gives full control over dot shapes (rounded, classy, extra-rounded), corner square styles, corner dot styles, colors, gradients, and logo embedding with automatic error correction adjustment.
The library renders to a canvas element and exposes getRawData() for blob extraction. This means downloads are just file-saver's saveAs() with a proper filename - no server roundtrip, no blob URL UUID problems.
For the live preview, the library re-instantiates on every option change and appends to a ref-tracked div. React handles the reactivity; the library handles the rendering. Clean separation.
Why Client-Side Everything
The entire data pipeline is browser-local:
1. QR String Building - buildQRString() takes structured data (WiFi credentials, vCard fields, UPI params) and formats it into standard QR encoding strings.
2. Canvas Rendering - QRCodeStyling generates the QR as a canvas/SVG element.
3. Download - getRawData('png'|'svg') extracts the blob, saveAs() triggers the browser download.
4. History & Templates - localStorage with JSON serialization. Last 10 QR codes stored.
5. Logo Embedding - FileReader.readAsDataURL() converts the uploaded image to base64 in-memory.
6. Watermark - Canvas API draws text below the QR image before blob extraction.
7. PDF Export - jsPDF renders the QR canvas to a PDF document entirely in-memory.
The only external call is URL shortening, which goes through a Vercel serverless function (/api/shorten) that proxies to is.gd because is.gd doesn't send CORS headers for browser-direct requests.
Why Tailwind CSS
Same reasoning as the portfolio site. Utility-first styling means I write components and style them in the same file. The dark theme uses CSS custom properties (--background, --foreground) defined in index.css, and Tailwind references them via bg-background, text-foreground, etc.
The monospace typography (JetBrains Mono) gives the entire app a technical, tool-like aesthetic that matches the audience - developers and power users who expect precision from their tools.
Why TypeScript
The app has seven distinct QR data types, each with their own interface (WiFiData, VCardData, UPIData, EventData, SMSData, EmailData, plus plain text). TypeScript guarantees that buildQRString() receives the correct shape for each type. When I added UPI support, the compiler immediately flagged every form handler that needed updating.
The QROptions interface ensures the preview, customization panel, and download handler all agree on what options look like. Add a new option in one place, TypeScript shows you every component that needs to handle it.
Vercel Deployment Strategy
The app is a static SPA served from Vercel's edge CDN with specific optimizations:
SPA Rewrites - All routes fallback to index.html so client-side routing works on direct navigation and page refresh.
Immutable Asset Caching - Hashed JS/CSS bundles in /assets/ get Cache-Control: public, max-age=31536000, immutable. Users cache vendor chunks forever; only the entry chunk changes on deploys.
Vendor Chunk Splitting - Vite's manualChunks splits the bundle into 5 cacheable groups: React core, Radix UI components, QR library, export libs (jsPDF + JSZip + file-saver), and Recharts.
Security Headers - X-Content-Type-Options: nosniff, X-Frame-Options: DENY, X-XSS-Protection, strict referrer policy, and camera-only permissions policy.
Fluid Compute - The /api/shorten function uses Vercel Fluid Compute for concurrent request handling on a single instance.
SEO Strategy
Even though this is a client-side SPA, SEO is handled through structured data and meta optimization:
JSON-LD markup for WebApplication (with feature list, pricing, and aggregate rating), Organization, BreadcrumbList, and FAQPage (5 Q&As targeting common search queries).
17 targeted keywords covering variations: 'QR code generator', 'free QR code', 'QR code maker', 'custom QR code', 'bulk QR codes', 'WiFi QR code', 'vCard QR code'.
Canonical URL, XML sitemap, robots.txt, max-image-preview:large for rich search results.