Shane32/QRCoder
A pure C# Open Source QR Code implementation
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓10 active contributors
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ⚠Single-maintainer risk — top contributor 84% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/shane32/qrcoder)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/shane32/qrcoder on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Shane32/QRCoder
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Shane32/QRCoder shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 3w ago
- 10 active contributors
- MIT licensed
- CI configured
- ⚠ Single-maintainer risk — top contributor 84% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Shane32/QRCoder
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Shane32/QRCoder.
What it runs against: a local clone of Shane32/QRCoder — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Shane32/QRCoder | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 50 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Shane32/QRCoder. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Shane32/QRCoder.git
# cd QRCoder
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Shane32/QRCoder and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Shane32/QRCoder(\\.git)?\\b" \\
&& ok "origin remote is Shane32/QRCoder" \\
|| miss "origin remote is not Shane32/QRCoder (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "QRCoder/QRCodeGenerator.cs" \\
&& ok "QRCoder/QRCodeGenerator.cs" \\
|| miss "missing critical file: QRCoder/QRCodeGenerator.cs"
test -f "QRCoder/QRCode.cs" \\
&& ok "QRCoder/QRCode.cs" \\
|| miss "missing critical file: QRCoder/QRCode.cs"
test -f "QRCoder/PayloadGenerator.cs" \\
&& ok "QRCoder/PayloadGenerator.cs" \\
|| miss "missing critical file: QRCoder/PayloadGenerator.cs"
test -f "QRCoder/AbstractQRCode.cs" \\
&& ok "QRCoder/AbstractQRCode.cs" \\
|| miss "missing critical file: QRCoder/AbstractQRCode.cs"
test -f "QRCoder/QRCodeData.cs" \\
&& ok "QRCoder/QRCodeData.cs" \\
|| miss "missing critical file: QRCoder/QRCodeData.cs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 50 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~20d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Shane32/QRCoder"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
QRCoder is a pure C# library (zero external dependencies) that generates QR codes and Micro QR codes in multiple output formats (PNG, SVG, PDF, ASCII, Bitmap, PostScript). It includes 23+ payload generators for structured data like WiFi credentials, vCards, Bitcoin addresses, and calendar events—enabling developers to create scannable codes that trigger specific actions on mobile devices. Modular monorepo structure: QRCoder/ contains the core engine with AbstractQRCode base class and format-specific implementations (ASCIIQRCode.cs, BitmapByteQRCode.cs, ArtQRCode.cs). PayloadGenerator/ subfolder contains 20+ specialized payload classes (Bitcoin, vCard, WiFi, etc.) that inherit from Payload base. QRCoder.Xaml/ is a separate WPF/XAML renderer project. Extensions/ folder provides reusable BitArray, Stream, and String utilities.
👥Who it's for
C# developers (both .NET Framework 3.5+ and .NET 5+ users) building desktop applications, web services, or mobile apps who need to embed QR code generation without external dependencies. Common use cases: e-commerce systems embedding payment QR codes, contact management apps generating vCard QR codes, and logistics platforms creating product tracking codes.
🌱Maturity & risk
Production-ready and actively maintained. The project shows strong maturity with automated CI/CD pipelines (wf-build-release-ci.yml, wf-build-test.yml), code coverage tracking via CodeCov, cross-platform support across multiple .NET versions, and a comprehensive wiki. The maintainer (Shane32) actively manages issues and releases on NuGet.
Low risk. Zero external runtime dependencies (only framework dependencies) eliminates supply chain concerns. The codebase is well-established with structured exception handling (Exceptions/ directory), attribute-based validation, and organized payload generators. Single maintainer (Shane32) is a potential concern for long-term sustainability, though the codebase's maturity and straightforward scope mitigate this.
Active areas of work
Active development with CI/CD focused on verification (wf-verify-formatting.yml suggests recent code quality enforcement). GitHub Actions workflows for build, test, and release automation indicate continuous integration. The presence of FUNDING.yml and Release notes/Changelog suggests regular versioning and community support is ongoing.
🚀Get running
git clone https://github.com/Shane32/QRCoder.git
cd QRCoder
dotnet build QRCoder.sln
dotnet test
The project uses standard .NET tooling (no npm/package.json); all dependencies are managed via .csproj files and Directory.Build.props for centralized configuration.
Daily commands:
dotnet build QRCoder.sln -c Release
dotnet test
No dev server; this is a library. To test functionality, create a console app referencing the QRCoder NuGet package or built assembly, then use PngByteQRCodeHelper.GetQRCode() or instantiate QRCodeGenerator and renderers directly.
🗺️Map of the codebase
QRCoder/QRCodeGenerator.cs— Core QR code generation engine; implements the main algorithm for creating QR code data structures and patterns.QRCoder/QRCode.cs— High-level QR code abstraction; entry point for most user-facing QR code generation workflows.QRCoder/PayloadGenerator.cs— Factory and base class for all payload types; defines the contract that all specialized encodings (WiFi, vCard, SMS, etc.) must implement.QRCoder/AbstractQRCode.cs— Abstract base class for all output format renderers (PNG, SVG, PDF, ASCII); defines rendering interface that all output modules inherit.QRCoder/QRCodeData.cs— Represents the raw QR code matrix data; bridges generated code patterns with format-specific renderers.QRCoder/QRCodeGenerator/ModulePlacer.cs— Handles placement of QR code modules (data, format, version info, alignment patterns); critical for spec compliance.QRCoder/QRCodeGenerator/CapacityTables.cs— Lookup tables for QR code capacity by version and error correction level; ensures data fit validation.
🛠️How to make changes
Add a new payload type (e.g., AppleWallet, custom protocol)
- Create new class in QRCoder/PayloadGenerator/ inheriting from Payload base class (
QRCoder/PayloadGenerator/YourNewPayload.cs) - Implement GetType() and ToString() methods following vCard/WiFi pattern for validation and encoding (
QRCoder/PayloadGenerator/YourNewPayload.cs) - Add factory method to PayloadGenerator.cs to route to your new type (
QRCoder/PayloadGenerator.cs) - Write unit tests matching the QRCoderApiTests pattern to validate output string format (
QRCoderApiTests/YourNewPayloadTests.cs)
Add a new output format renderer (e.g., WebP, GIF, Base32)
- Create new class inheriting from AbstractQRCode<T> in QRCoder/ directory (
QRCoder/YourFormatQRCode.cs) - Implement required RenderGraphics() method to convert QRCodeData matrix to your format (
QRCoder/YourFormatQRCode.cs) - Add factory method or extension in QRCode.cs wrapper class to surface the new renderer (
QRCoder/QRCode.cs) - Add performance benchmark in QRCoderBenchmarks/ to track rendering speed (
QRCoderBenchmarks/YourFormatQRCodeBenchmark.cs)
Optimize data encoding for a new character set or mode
- Create new DataSegment class in QRCoder/QRCodeGenerator/ (e.g., KanjiDataSegment pattern) (
QRCoder/QRCodeGenerator/YourModeDataSegment.cs) - Implement required encoding logic and character capacity calculations per QR spec (
QRCoder/QRCodeGenerator/YourModeDataSegment.cs) - Register new mode in OptimizedDataSegment.cs segmentation logic to auto-select when beneficial (
QRCoder/QRCodeGenerator/OptimizedDataSegment.cs) - Update CapacityTables.cs if new version/ECC combinations required (
QRCoder/QRCodeGenerator/CapacityTables.cs)
Support a new QR code standard variant (e.g., Micro QR, rMQR)
- Extend QRCodeGenerator.cs with new version/capacity enums and VersionInfo mappings (
QRCoder/QRCodeGenerator.cs) - Update ModulePlacer.cs to handle alternate finder pattern, timing, and alignment logic if differs from ISO 18004 (
QRCoder/QRCodeGenerator/ModulePlacer.cs) - Adjust CapacityTables.cs with new spec data capacity rows for the variant (
QRCoder/QRCodeGenerator/CapacityTables.cs) - Test renderers (PngByteQRCode, SvgQRCode, etc.) against new module layouts (
QRCoder/PngByteQRCode.cs)
🪤Traps & gotchas
No obvious required environment variables or external services. Watch for: .snk (StrongName key) files in QRCoder.Xaml/ suggest strong naming is used—needed for certain .NET scenarios. PostScript output uses embedded string literals (not external tools), so no ghostscript or ImageMagick dependency. Target framework support is wide (3.5 to .NET 5+)—test your usage against all supported versions if contributing. The Attributes/ folder includes custom NotNullWhenAttribute suggesting nullable reference type validation is enforced.
🏗️Architecture
💡Concepts to learn
- Reed-Solomon Error Correction — QRCoder's ECCLevel (L/M/Q/H) relies on Reed-Solomon codes to recover data if the QR code is partially damaged; understanding ECC trade-offs between capacity and durability is critical for choosing correct error correction levels
- Galois Field (GF(2^8)) Arithmetic — Reed-Solomon implementation in QRCoder uses GF(256) polynomial math for encoding/decoding; understanding this finite field arithmetic is essential for contributing to core error correction logic
- QR Code Capacity Planning (Data Encoding Modes) — QRCoder selects numeric, alphanumeric, or byte encoding modes based on input; understanding mode switching optimizes code size and is crucial for payload generator design
- Micro QR Codes — QRCoder supports Micro QR (M1-M4) alongside standard QR; these are smaller variants with reduced error correction, important for space-constrained use cases like component labeling
- Template Method Pattern (AbstractQRCode) — The core architecture uses Template Method to define the QR generation pipeline; new format implementations override specific steps, making this pattern foundational to extending QRCoder
- PostScript Vector Graphics — QRCoder can output PostScript format (a page description language); understanding PostScript operators (moveto, lineto) helps implement or debug the PostScript renderer
- vCard (RFC 2426 / RFC 6350) Format — ContactData.cs generates vCard-formatted QR codes for contact exchange; knowing vCard syntax and version differences (v3 vs v4) is essential for the payload generator module
🔗Related repos
codebude/QRCoder— Original upstream QRCoder repository by Raffael Herrmann (Shane32's fork is a maintained continuation); reference for architectural decisions and historical contextjboss-fuse/zxing— ZXing is the closest .NET alternative (port from Java); offers different format support and encoding strategies useful for comparisondotnet/runtime— BCL (Base Class Library) provides all underlying dependencies used by QRCoder (BitArray, Stream, Collections); understanding framework APIs is essentialdotnet/winforms— Rendering QR codes in WinForms applications is a common use case; QRCoder.Xaml provides WPF support but WinForms integration examples are valuableaspnet/AspNetCore— Web developers often embed QR codes in ASP.NET Core pages; QRCoder integrates cleanly into HTTP response streams for dynamic generation
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for PayloadGenerator implementations
The repo has 20+ PayloadGenerator implementations (Bitcoin, Girocode, WiFi, SMS, etc.) but no visible test files in the file structure. Given the complexity of payload formatting and validation rules (e.g., vCard RFC compliance, Girocode SEPA specs), adding targeted unit tests would prevent regressions and validate format compliance against real-world standards referenced in ContactData_vCard3_rfc2426.txt and ContactData_vCard4_rfc6350.txt.
- [ ] Create QRCoder.Tests/PayloadGenerator/ContactDataTests.cs to validate vCard3/vCard4 format compliance against RFC specs
- [ ] Create QRCoder.Tests/PayloadGenerator/GirocodeTests.cs and SwissQrCodeTests.cs for banking payload validation
- [ ] Create QRCoder.Tests/PayloadGenerator/WiFiTests.cs to test special character escaping and security type handling
- [ ] Add parameterized tests for edge cases (empty strings, max lengths, special characters) across all payload types
Add XML documentation generation and publish to docs site
The codebase has well-organized public APIs (QRCode.cs, QRCodeGenerator.cs, 20+ PayloadGenerator classes) but no visible <summary>, <param>, <returns> XML documentation tags. With zero external dependencies as a key selling point, comprehensive auto-generated API docs would improve discoverability. The repo has .github/docu/ folder suggesting docs infrastructure exists.
- [ ] Add <summary>, <param>, <returns>, and <example> XML doc comments to QRCode.cs and AbstractQRCode.cs base classes
- [ ] Add XML docs to all PayloadGenerator/Payload.cs interfaces and major implementations (ContactData, WiFi, Girocode)
- [ ] Update Directory.Build.targets to enable DocFX or Sandcastle documentation generation with GenerateDocumentationFile flag
- [ ] Create .github/workflows/wf-build-docs.yml to auto-publish generated docs on releases
Refactor monolithic QRCodeGenerator.cs into focused encoder modules
The file structure shows QRCoder/QRCodeGenerator/ subdirectory with AlphanumericEncoder.cs, AlphanumericDataSegment.cs, ByteDataSegment.cs etc., but these appear to be split out while QRCodeGenerator.cs likely remains large. Completing the refactor by extracting remaining encoding logic (Kanji, ECI, numeric modes) into dedicated mode-specific classes would improve maintainability and make contribution easier.
- [ ] Audit QRCodeGenerator.cs to identify numeric, Kanji, and ECI encoding logic blocks
- [ ] Create QRCoder/QRCodeGenerator/NumericDataSegment.cs and NumericEncoder.cs following AlphanumericDataSegment.cs pattern
- [ ] Create QRCoder/QRCodeGenerator/KanjiDataSegment.cs and KanjiEncoder.cs with charset handling
- [ ] Create QRCoder/QRCodeGenerator/ECIEncoder.cs and extract ECI mode logic; update QRCodeGenerator.cs to compose these modules
🌿Good first issues
- Add unit tests for PayloadGenerator/MoneroTransaction.cs, BitcoinCashAddress.cs, and RussiaPaymentOrder.cs—these specialized payload classes likely lack test coverage compared to generic types like ContactData.cs
- Create documentation/examples for using ArtQRCode.cs with the logo/styling features—the class exists but the quick-start README only covers basic PNG/SVG generation
- Implement missing PostScript output renderer tests—PostScript is listed in features but only 2588 bytes of PostScript code exists; verify rendering correctness and add integration tests against PostScript validators
⭐Top contributors
Click to expand
Top contributors
- @Shane32 — 84 commits
- @codebude — 6 commits
- @TimothyMakkison — 3 commits
- @danFbach — 1 commits
- @Copilot — 1 commits
📝Recent commits
Click to expand
Recent commits
4b97eb1— a couple places where ArtQRCode creates a short lived Bitmap but neve… (#695) (danFbach)443d5a1— Fix EPS protocol violations in PostscriptQRCode: remove showpage and setpagedevice from EPS output (#694) (Shane32)4973174— Fix PDF spec compliance, git line-ending corruption, and add xref validation test (#691) (Copilot)ac4aac0— Optimize alphanumeric encoder and galois field constants (#684) (Shane32)359ad78— Add multi mode encoding (#676) (Shane32)fd548fb— Prep DataSegment for multi mode QR codes (#683) (Shane32)80448a1— Fix condition for ISO-8859-1 encoding selection in GetTargetEncoding method (#681) (Shane32)6cd987c— Use SDK 8.0 recommended analyzers (#680) (Shane32)46d8fbf— Add ISO-8859-2 encoding support instructions to README (#678) (Shane32)8e46159— Refactor DataSegment handling for improved encoding support (#677) (Shane32)
🔒Security observations
QRCoder demonstrates a strong security posture for a pure C# QR code generation library. The codebase has zero external dependencies, which eliminates supply chain risks. No hardcoded secrets, SQL injection vectors, XSS vulnerabilities, or infrastructure misconfigurations were detected. The primary concern identified is the presence of a strong name key file in version control, which is a minor issue if properly managed. The library's focused functionality (QR code generation) and lack of network/database operations further contribute to its security. Recommendations focus on input validation best practices for the PayloadGenerator classes to ensure robust handling of diverse data types.
- Low · Strong Name Key File Exposed in Repository —
QRCoder.Xaml/QRCoder.XamlStrongName.snk. The file QRCoder.Xaml/QRCoder.XamlStrongName.snk is a strong name key file that should typically be kept private and not committed to version control. If this is a private key, it could be used to sign assemblies maliciously. Fix: Add *.snk files to .gitignore. If this key has been exposed, consider regenerating it and updating any signing processes. Store strong name keys securely outside of version control. - Low · Potential Input Validation in PayloadGenerator Classes —
QRCoder/PayloadGenerator/*.cs. Multiple PayloadGenerator classes (Email, URL, PhoneNumber, etc.) accept user input for QR code generation. While QR codes themselves are not injection vectors, improper validation of input data before encoding could lead to issues if the generated QR codes are used in contexts where they're parsed or interpreted. Fix: Implement comprehensive input validation for all PayloadGenerator classes. Validate email formats, URLs, phone numbers, and other data according to their respective standards. Document any limitations on accepted characters.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.