npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@satirr/openqtr

v0.3.0

Published

OpenQRL is an open-source website for creating and customizing QR codes with an elegant Frutiger Aero dusk theme. Built with Next.js 15, TypeScript, and Tailwind CSS v4.

Readme

OpenQRL

OpenQRL is an open-source website for creating and customizing QR codes with an elegant Frutiger Aero dusk theme. Built with Next.js 15, TypeScript, and Tailwind CSS v4.

Features

5 QR Types

  • Text — Plain text
  • URL — Website link (auto-prepends https://)
  • Email — Email address with optional subject & body
  • Wi-Fi — Wi-Fi credentials (SSID, encryption, password, hidden toggle)
  • vCard — Complete contact (name, phone, email, org, title, website, address)

Style Customization

  • Colors: Data / Finder / Background (color picker + hex input)
  • Gradient Fill: Linear gradient with customizable angle & two colors (Solid/Gradient toggle)
  • Dot Shape: Square, Dots, Rounded, Classy, Soft
  • Error Correction: L (~7%), M (~15%), Q (~25%), H (~30%)
  • Size: Slider 160–400px
  • Margin: Slider 0–40px
  • Logo: File upload (drag & drop or click), image URL, size slider, hide-dots toggle

Export

  • PNG (raster, 2x scale)
  • JPG (raster, quality 0.95)
  • SVG (vector, scalable)

History

  • Auto-saves QR configuration on export (colors, shape, content, logo)
  • Per-entry format buttons (PNG / JPG / SVG) for re-download
  • Persisted to localStorage — survives page refresh

Undo / Redo

  • Tracks style, color, logo, content, and QR type changes
  • Up to 50 undo levels
  • Buttons in the Style panel header

UX & Performance

  • 350ms debounce + onBlur commit (avoids per-keystroke re-render)
  • Zustand selectors (narrow subscriptions, no cascading re-renders)
  • Responsive: split layout on desktop, stacked on mobile
  • Dark glass panels with premium shadows
  • Dusk gradient background: navy → purple → sunset + stars + bubbles + ground mist

Script SDK (OpenQTR)

OpenQTR (Open QR Tool Renderer) is a standalone browser SDK that lets anyone generate QR codes from any website — no React, no framework, no bundler needed.

<script src="https://cdn.jsdelivr.net/npm/@satirr/openqtr/dist/sdk.js"></script>
<div id="qr"></div>
<script>
  OpenQTR.generate({
    text: "Hello World",
    element: "#qr",
    size: 250,
  });
</script>

| Feature | Description | |---------|-------------| | Formats | PNG (canvas) & SVG | | Colors | Custom fgColor & bgColor | | Error correction | L / M / Q / H | | CDN | jsDelivr — zero setup | | Self-host | /openqtr-sdk.js when running the app |

See the full API guide at /GUIDE-API or read GUIDE-API.md for the expert reference.


Tech Stack

| Layer | Technology | |-------|-----------| | Framework | Next.js 15 (App Router, Turbopack) | | Language | TypeScript (strict mode) | | Styling | Tailwind CSS v4 | | State | Zustand v5 (persist middleware for history) | | QR Engine | qrcode (matrix generation) + custom Canvas/SVG renderers | | Icons | lucide-react | | Font | Inter (via next/font) |


Project Structure

openqrl/
├── app/
│   ├── globals.css          # Design tokens, glass utilities, animations
│   ├── layout.tsx           # Root layout + Inter font + metadata
│   └── page.tsx             # Main page: header, split panels, footer
├── components/
│   ├── BackgroundEffect.tsx # Dusk gradient, stars, sunset glow, bubbles, mist
│   ├── ExportButtons.tsx    # PNG / JPG / SVG download buttons
│   ├── HistoryPanel.tsx     # Collapsible history, per-entry re-export, clear
│   ├── LogoUploader.tsx     # Dropzone + URL input + hidden file input (always mounted)
│   ├── QRForm.tsx           # Dynamic form per QR type, onBlur commit
│   ├── QRPreview.tsx        # Sticky right panel, debounced QR render
│   ├── QRTypeSelector.tsx   # 5 tab buttons with icons, cyan active state
│   ├── StylePanel.tsx       # Color pickers, gradient, dot shapes, ECC, size/margin, undo/redo
│   └── UpdateModal.tsx      # One-time v0.2.0 changelog notification modal
├── lib/
│   ├── qrCore.ts            # Custom QR rendering (HTML, Canvas, SVG export)
│   ├── qrData.ts            # Generate QR content string per type
│   ├── store.ts             # Zustand store: formData, style, logo, history, undo/redo
│   └── useDebounce.ts       # Generic debounce hook
├── types/
│   └── index.ts             # QRType, DotType, QRFormData, StyleOptions, etc.
├── public/                  # Static assets (SVG icons)
├── .gitignore
├── eslint.config.mjs
├── LICENSE.md               # Apache 2.0
├── next.config.ts
├── package.json
├── postcss.config.mjs
├── README.md
└── tsconfig.json

Getting Started

Prerequisites

  • Node.js 18+
  • npm / pnpm / yarn / bun

Installation & Development

# Clone repo
git clone https://gitlab.com/satirr/openqtr.git
cd openqrl

# Install dependencies
npm install

# Start development server
npm run dev

Open http://localhost:3000 in your browser.

Production Build

npm run build
npm start

Key Configuration Details

Design Tokens (app/globals.css)

:root {
  --glass-bg: rgba(15, 18, 28, 0.9);
  --glass-border: rgba(255, 255, 255, 0.08);
  --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  --accent-cyan: #00f5d4;
  --radius-input: 12px;
  --radius-panel: 16px;
}

Layout Container (app/page.tsx)

<div className="max-w-5xl mx-auto px-6 lg:px-16 xl:px-24">
  <div className="flex gap-6 lg:justify-center">
    {/* Left: w-full lg:w-auto lg:max-w-2xl */}
    {/* Right: lg:w-80 xl:w-96 shrink-0 sticky top-24 */}
  </div>
</div>

Debounce & Commit (lib/useDebounce.ts, components/QRForm.tsx)

// Commits to store on blur, not on every keystroke
const debouncedValue = useDebounce(value, 350);
<input onBlur={() => commit()} ... />

getCornerType() — Outside Component

// components/QRPreview.tsx (~line 15)
function getCornerType(dotType: DotType): 'square' | 'dot' | 'rounded' | 'classy' | 'extra-rounded' {
  // mapping...
}

Prevents infinite loop inside useEffect.

File Input Always Mounted (components/LogoUploader.tsx)

// Always in DOM, never conditionally rendered
<input
  type="file"
  ref={fileInputRef}
  className="hidden"
  onChange={handleFileChange}
/>

Prevents uncontrolled → controlled React error.


Theme & Colors

Dusk Gradient Background

Navy (#0a0f1f) → Deep Purple (#1a0a2e) → Sunset Orange (#2d1018)
  • 20 animated stars (twinkle)
  • 8 rising bubbles (bubbleUp)
  • Sunset glow (glowPulse)
  • Ground mist (translateY animation)

Glass Panel Variants

  • Default: bg-white/5 backdrop-blur-xl border-white/10
  • Shimmer: + animated gradient overlay
  • Strong: bg-white/10 backdrop-blur-2xl border-white/15 shadow-[0_8px_32px_rgba(0,0,0,0.4)]

Accent Cyan

#00f5d4 — used for:

  • Active tab indicator
  • Button hover/active states
  • Slider thumb & track
  • Focus rings
  • Logo upload zone border

Dependencies

Production

{
  "next": "^15.1.0",
  "react": "^19.0.0",
  "react-dom": "^19.0.0",
  "zustand": "^5.0.0",
  "qrcode": "^1.5.4",
  "lucide-react": "^0.468.0"
}

Development

{
  "typescript": "^5",
  "@types/node": "^20",
  "@types/react": "^19",
  "@types/react-dom": "^19",
  "tailwindcss": "^4",
  "@tailwindcss/postcss": "^4"
}

QR Data Formats

Wi-Fi

WIFI:S:<SSID>;T:<WPA|WEP|nopass>;P:<password>;;

vCard (v3.0)

BEGIN:VCARD
VERSION:3.0
FN:<Full Name>
TEL:<Phone>
EMAIL:<Email>
ORG:<Organization>
ADR:<Address>
END:VCARD

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/feature-name
  3. Commit your changes: git commit -m "feat: add feature X"
  4. Push: git push origin feature/feature-name
  5. Open a Pull Request

License

Apache License 2.0 — see LICENSE.md for full details.

Copyright 2025 Satir
Licensed under the Apache License, Version 2.0

Demo & Result

OpenQRL Site


Author & Community

Created by Satir

💬 Join WhatsApp Channel: bit.ly/tirrch


Acknowledgments


OpenQRL — Make QR codes beautiful again.