Skip to main content

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

QRGen

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.

Live: https://qrgen.korak-dev.uk/

Source: https://github.com/Korak-997/qrgen

Technical Hurdles

01

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.

02

"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.

03

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.