Case Study
QRGen
"A fast, privacy-first QR studio—premium styling and logo embedding without paywalls, watermarks, or noise."
Role
Product, design, and engineering (solo)
Duration
Ongoing · open source
Path
~/projects/qrgen
Tech Stack
Vue 3, TypeScript, Vite, Tailwind CSS, DaisyUI, qr-code-styling, VueUse, vue-advanced-cropper, Lucide
The Problem
The QR space is full of half-solutions: "free" generators that watermark downloads, cap resolution, or hide basic styling behind subscriptions; cluttered interfaces built for ad inventory, not clarity; and hosted flows that ask you to trust an opaque backend with the very URLs and text you're encoding. For anyone shipping branded materials—or just caring about privacy—that's a frustrating set of tradeoffs.
The Solution
QRGen is how I chose to invert that model: no ads, no accounts, no server-side generation of your content. I built it as a Vue 3 + Vite + TypeScript app with a dual-pane workflow—controls on one side, a live preview on the other—using qr-code-styling for the hard parts (rounded modules, gradients, reliable rendering). I treated branding as a first-class flow: upload a logo, crop it in place, and keep scan reliability in mind with sensible defaults. The result is a tool that feels like a small studio product while staying MIT-licensed and inspectable on GitHub.
Context
QR codes are small, but the ecosystem around them is noisy. Many tools optimize for conversion funnels and upsells: watermarked downloads, resolution caps, or "unlock SVG" moments. Others simply feel dated—cluttered pages, inconsistent previews, and flows that assume you are fine handing your URL or copy to a remote service you cannot inspect.
I started QRGen from a simpler bar: if the feature is part of a professional workflow, it should not require a ransom note.
What I built
QRGen is a browser-based studio for generating QR codes with live preview and deep visual control—dot patterns, finder "eye" shapes, and solid or gradient treatments that still respect the basic rules of scannability. I made branding a first-class workflow: upload a logo, crop it in the app, and place it confidently in the center without a separate image editor.
Technically, I built it as a Vue 3 single-page experience with Vite and TypeScript, styled with Tailwind CSS and DaisyUI, and used practical composables from VueUse where the browser mattered. I delegated rendering complexity to qr-code-styling, which is purpose-built for styled QR output. Icons are Lucide; the cropping step uses vue-advanced-cropper so the logo flow feels tight rather than improvised.
How I designed the interaction
I used a dual-pane rhythm: a configuration surface (grouped controls) and a preview surface that stays visually anchored—iterate, then download a high-resolution PNG without watermarks. Dark mode and glass-style surfaces are not decoration for their own sake; I wanted long tweaking sessions to stay readable and a bit more "tool-like" than "landing page-like."
Privacy and trust
My story is straightforward: generation happens client-side. The payload I type is not shipped to a bespoke backend to be turned into an image. In the open-source baseline, I also aimed to avoid invasive tracking—if I want trust in a utility, the bundle should behave like one.
Outcome
QRGen is my free, open (MIT) answer to a crowded category: fewer compromises, fewer dark patterns, and a codebase someone can read before they rely on it. I cared about the details people actually notice: speed of iteration, export quality, logo support, and an interface that respects attention.
Technical Hurdles
Styling without breaking scannability
Gradients, dot styles, and logo overlays look great until they don't scan. I had to balance expressiveness with contrast, quiet areas around the finder patterns, and logo sizing—then keep checking real-world scans, not just the preview.
"Premium" UX with a zero-friction promise
Advanced controls can read as complexity. I focused on progressive disclosure—accordions/tabs, clear grouping—so beginners get a fast path while I still expose granular control over eyes, dots, and color.
A privacy story that matches the implementation
I only wanted to claim client-side generation if the architecture backed it: generation and export stay in the browser, dependencies stay purposeful, and the baseline avoids invasive analytics. That consistency became part of the product, not a footnote.
Evolution & Insights
- I paired a sharp problem (utility category fatigue) with a sharp constraint: client-side, no account wall.
- I let a focused library own rendering complexity and spent my time on preview speed and exports I'd trust.
- I treated discoverability of advanced features as part of polish—styling power shouldn't mean a confusing layout.
- I shipped MIT licensing so privacy and behavior are things people can verify, not just copy on a landing page.