<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akansh Sirohi</title>
    <description>The latest articles on DEV Community by Akansh Sirohi (@akanshsirohi).</description>
    <link>https://dev.to/akanshsirohi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F607403%2F6544040d-e6c5-4249-a6e1-2c0d5f4e8e64.jpeg</url>
      <title>DEV Community: Akansh Sirohi</title>
      <link>https://dev.to/akanshsirohi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akanshsirohi"/>
    <language>en</language>
    <item>
      <title>I Built a QR-Inspired Code That Uses 4 Colors, Stores More Data, and Supports Encryption</title>
      <dc:creator>Akansh Sirohi</dc:creator>
      <pubDate>Fri, 21 Aug 2026 17:51:20 +0000</pubDate>
      <link>https://dev.to/akanshsirohi/i-built-a-qr-inspired-code-that-uses-4-colors-stores-more-data-and-supports-encryption-195d</link>
      <guid>https://dev.to/akanshsirohi/i-built-a-qr-inspired-code-that-uses-4-colors-stores-more-data-and-supports-encryption-195d</guid>
      <description>&lt;p&gt;QR codes are everywhere.&lt;/p&gt;

&lt;p&gt;Payments, login flows, restaurant menus, Wi-Fi sharing, tickets, product packaging, device pairing, authentication, links. They have become one of those technologies that quietly works almost everywhere.&lt;/p&gt;

&lt;p&gt;And there is a very good reason for that.&lt;/p&gt;

&lt;p&gt;QR Code is mature, standardized, extremely well optimized, and surprisingly resilient.&lt;/p&gt;

&lt;p&gt;But while working with QR codes, I kept thinking about one simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why are we still representing data using only two visible states when the cameras scanning these codes can distinguish millions of colors?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A traditional QR data module is effectively binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Black → one state
White → another state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So one data module represents one binary choice.&lt;/p&gt;

&lt;p&gt;Modern cameras, displays, image processing, and computing hardware are far more capable than when QR Code was originally designed.&lt;/p&gt;

&lt;p&gt;That led me to an experiment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens if a QR-inspired matrix code uses four reliably distinguishable visual states instead of two?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That experiment became &lt;strong&gt;QuadQR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;QuadQR is an experimental open-source 2D matrix-code format that uses &lt;strong&gt;Red, Green, Blue, and White&lt;/strong&gt; as its four data states.&lt;/p&gt;

&lt;p&gt;It now includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 bits per data cell&lt;/li&gt;
&lt;li&gt;RGBW color calibration&lt;/li&gt;
&lt;li&gt;perspective correction&lt;/li&gt;
&lt;li&gt;camera scanning&lt;/li&gt;
&lt;li&gt;image scanning&lt;/li&gt;
&lt;li&gt;Reed-Solomon error correction&lt;/li&gt;
&lt;li&gt;confidence-assisted error recovery&lt;/li&gt;
&lt;li&gt;spectral-spatial interleaving&lt;/li&gt;
&lt;li&gt;CRC integrity checking&lt;/li&gt;
&lt;li&gt;optional AES-256-GCM encrypted payloads&lt;/li&gt;
&lt;li&gt;password and raw-key security modes&lt;/li&gt;
&lt;li&gt;multiple scanner-safe visual styles&lt;/li&gt;
&lt;li&gt;Node.js and browser APIs&lt;/li&gt;
&lt;li&gt;CLI support&lt;/li&gt;
&lt;li&gt;npm distribution&lt;/li&gt;
&lt;li&gt;benchmark tooling&lt;/li&gt;
&lt;li&gt;a documented wire format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yes, you can already generate and scan one in your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://akanshsirohi.github.io/QuadQR/demo/" rel="noopener noreferrer"&gt;https://akanshsirohi.github.io/QuadQR/demo/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://akanshsirohi.github.io/QuadQR/docs-site/" rel="noopener noreferrer"&gt;https://akanshsirohi.github.io/QuadQR/docs-site/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/akanshSirohi/QuadQR" rel="noopener noreferrer"&gt;https://github.com/akanshSirohi/QuadQR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/quadqr-js" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/quadqr-js&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The basic idea
&lt;/h2&gt;

&lt;p&gt;The core idea is surprisingly simple.&lt;/p&gt;

&lt;p&gt;A binary module gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 possible states

log2(2) = 1 bit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we can reliably distinguish four states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4 possible states

log2(4) = 2 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So QuadQR uses:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Color&lt;/th&gt;
&lt;th&gt;Bits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Red&lt;/td&gt;
&lt;td&gt;&lt;code&gt;00&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Green&lt;/td&gt;
&lt;td&gt;&lt;code&gt;01&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blue&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;White&lt;/td&gt;
&lt;td&gt;&lt;code&gt;11&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One QuadQR data cell therefore carries exactly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An encoded byte contains 8 bits, so it maps naturally to four cells:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8 bits / 2 bits per cell = 4 cells
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no base-3 encoding, fractional packing, or unusual bit arithmetic required.&lt;/p&gt;

&lt;p&gt;It is simply a quaternary alphabet mapped directly onto binary pairs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why RGBW?
&lt;/h2&gt;

&lt;p&gt;I experimented with different possibilities while building QuadQR.&lt;/p&gt;

&lt;p&gt;Using more colors sounds attractive because, mathematically, more states can carry more information.&lt;/p&gt;

&lt;p&gt;For example, eight states could theoretically represent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log2(8) = 3 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there is a major problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A camera does not see colors the same way your source image does.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A perfect &lt;code&gt;(255, 0, 0)&lt;/code&gt; red pixel can become something completely different because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ambient lighting&lt;/li&gt;
&lt;li&gt;shadows&lt;/li&gt;
&lt;li&gt;reflections&lt;/li&gt;
&lt;li&gt;display brightness&lt;/li&gt;
&lt;li&gt;camera white balance&lt;/li&gt;
&lt;li&gt;printer ink&lt;/li&gt;
&lt;li&gt;paper color&lt;/li&gt;
&lt;li&gt;JPEG compression&lt;/li&gt;
&lt;li&gt;sensor noise&lt;/li&gt;
&lt;li&gt;exposure&lt;/li&gt;
&lt;li&gt;viewing angle&lt;/li&gt;
&lt;li&gt;screen color calibration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more colors you add, the closer those states become in color space and the easier they are to confuse.&lt;/p&gt;

&lt;p&gt;So instead of chasing the maximum theoretical density, I wanted a small set of colors with strong separation.&lt;/p&gt;

&lt;p&gt;The current QuadQR alphabet is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Red
Green
Blue
White
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And importantly, &lt;strong&gt;black is not used as payload data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Black remains useful for structural information such as finder patterns, timing structures, and alignment references.&lt;/p&gt;

&lt;p&gt;That separation makes detection significantly simpler.&lt;/p&gt;




&lt;h2&gt;
  
  
  QuadQR still looks familiar for a reason
&lt;/h2&gt;

&lt;p&gt;I did not want to completely reinvent the geometry of a matrix code.&lt;/p&gt;

&lt;p&gt;There are things traditional QR Code does extremely well.&lt;/p&gt;

&lt;p&gt;QuadQR therefore keeps several familiar ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;square overall matrix&lt;/li&gt;
&lt;li&gt;square modules&lt;/li&gt;
&lt;li&gt;three large finder patterns&lt;/li&gt;
&lt;li&gt;timing structures&lt;/li&gt;
&lt;li&gt;alignment references&lt;/li&gt;
&lt;li&gt;quiet zone&lt;/li&gt;
&lt;li&gt;masking&lt;/li&gt;
&lt;li&gt;error correction&lt;/li&gt;
&lt;li&gt;structured data placement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The major experiment happens primarily in the &lt;strong&gt;data representation and decoding pipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of interpreting data cells as black or white, QuadQR reconstructs the geometry and then classifies each payload position as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R
G
B
W
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also means white cannot simply mean "empty."&lt;/p&gt;

&lt;p&gt;The decoder first determines which matrix positions are structural and which are data cells.&lt;/p&gt;

&lt;p&gt;Only then does it classify the sampled data color.&lt;/p&gt;




&lt;h2&gt;
  
  
  Color calibration is essential
&lt;/h2&gt;

&lt;p&gt;Simply asking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pixel&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;RED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would fail almost immediately with a real camera.&lt;/p&gt;

&lt;p&gt;Instead, QuadQR includes known calibration references in the symbol.&lt;/p&gt;

&lt;p&gt;The scanner uses those references to understand what red, green, blue, white, and structural black actually look like &lt;strong&gt;inside the current image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So the scanner is not expecting perfect source RGB values.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generated red
↓
camera + lighting + screen + exposure
↓
observed reddish color
↓
calibration
↓
classified as QuadQR Red
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scanner can then perform nearest-color classification relative to the observed calibration values rather than blindly comparing against ideal RGB constants.&lt;/p&gt;

&lt;p&gt;That is one of the most important parts of making a color-based code practical.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scanning is much more than reading colors
&lt;/h2&gt;

&lt;p&gt;Generating the matrix is the easy part.&lt;/p&gt;

&lt;p&gt;Scanning it from a real-world image is where things become interesting.&lt;/p&gt;

&lt;p&gt;The current QuadQR scanner performs a pipeline roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera / Image
      ↓
Finder detection
      ↓
Alignment detection
      ↓
Perspective / homography correction
      ↓
Matrix reconstruction
      ↓
Module sampling
      ↓
Color calibration
      ↓
RGBW classification
      ↓
Unmasking
      ↓
Spectrum ECC / Reed-Solomon recovery
      ↓
CRC verification
      ↓
Payload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That allows QuadQR to handle perspective distortion instead of requiring the code to be perfectly aligned with the camera.&lt;/p&gt;

&lt;p&gt;Larger versions also use distributed alignment markers to give the scanner more geometric references.&lt;/p&gt;

&lt;p&gt;And the library supports both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;uploaded image scanning&lt;/li&gt;
&lt;li&gt;live camera scanning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;from the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  Error correction needed a color-aware approach
&lt;/h2&gt;

&lt;p&gt;A higher-density code is not very useful if one shadow makes it unreadable.&lt;/p&gt;

&lt;p&gt;So reliability became one of the biggest parts of the project.&lt;/p&gt;

&lt;p&gt;QuadQR uses &lt;strong&gt;GF(256) Reed-Solomon error correction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you have worked with QR Code, storage formats, CDs, networking protocols, or data transmission systems, you may already be familiar with Reed-Solomon.&lt;/p&gt;

&lt;p&gt;It allows a decoder to reconstruct damaged symbols using redundant parity information.&lt;/p&gt;

&lt;p&gt;QuadQR currently exposes four project-defined ECC profiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;L
M
Q
H
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Higher levels dedicate more space to redundancy and reduce the available payload capacity.&lt;/p&gt;

&lt;p&gt;But I wanted to take advantage of something a color scanner knows that a normal hard-decision decoder often throws away:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confidence.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Spectrum ECC
&lt;/h2&gt;

&lt;p&gt;I call the QuadQR-specific recovery system &lt;strong&gt;Spectrum ECC&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When the scanner looks at a data module, it does not only decide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is Blue.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also measures how confident that decision is.&lt;/p&gt;

&lt;p&gt;Imagine a sampled module where the calibrated color distances look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blue  = very close
Green = far away
Red   = very far
White = far away
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is probably a reliable Blue decision.&lt;/p&gt;

&lt;p&gt;But another module might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blue  = 42
Green = 45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the scanner has much less confidence.&lt;/p&gt;

&lt;p&gt;That information is valuable.&lt;/p&gt;

&lt;p&gt;QuadQR keeps a confidence score for every RGBW module.&lt;/p&gt;

&lt;p&gt;Four data modules form one GF(256) Reed-Solomon byte symbol, so those module confidences can be combined into a confidence score for the byte itself.&lt;/p&gt;

&lt;p&gt;Normally Reed-Solomon decoding first attempts conventional recovery.&lt;/p&gt;

&lt;p&gt;If that fails, QuadQR can identify the least-confident byte symbols and treat them as &lt;strong&gt;erasures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;An error says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Something is wrong somewhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An erasure says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This specific symbol is probably wrong.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reed-Solomon can use its available redundancy more efficiently when the decoder knows the likely location of the damage.&lt;/p&gt;

&lt;p&gt;So instead of throwing away the uncertainty produced by color classification, QuadQR feeds it back into error recovery.&lt;/p&gt;

&lt;p&gt;That is Spectrum ECC.&lt;/p&gt;




&lt;h2&gt;
  
  
  Spreading physical damage across the data
&lt;/h2&gt;

&lt;p&gt;There was another problem.&lt;/p&gt;

&lt;p&gt;Imagine a shadow covering one rectangular area of a code.&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a scratch&lt;/li&gt;
&lt;li&gt;glare&lt;/li&gt;
&lt;li&gt;folded paper&lt;/li&gt;
&lt;li&gt;ink damage&lt;/li&gt;
&lt;li&gt;a dirty camera lens&lt;/li&gt;
&lt;li&gt;a reflection from a display&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If neighboring physical cells also contain neighboring logical bytes, one localized defect can destroy a continuous part of the encoded stream.&lt;/p&gt;

&lt;p&gt;QuadQR therefore uses a deterministic &lt;strong&gt;spectral-spatial interleaver&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After error correction, logically neighboring codeword cells are redistributed across physically distant locations in the matrix.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Logical:

A A A A B B B B C C C C

Physical:

A D B F C A E B G C ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real permutation is deterministic and reversible, but that is the basic idea.&lt;/p&gt;

&lt;p&gt;Now a localized shadow or scratch is more likely to damage smaller parts of many Reed-Solomon symbols rather than completely destroying one contiguous region.&lt;/p&gt;

&lt;p&gt;And importantly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The interleaver does not consume additional data cells.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It changes placement, not capacity.&lt;/p&gt;




&lt;h2&gt;
  
  
  CRC as the final integrity check
&lt;/h2&gt;

&lt;p&gt;Reed-Solomon answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can this damaged information be reconstructed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But after decoding I still want a strong indication that the reconstructed payload matches what was originally encoded.&lt;/p&gt;

&lt;p&gt;QuadQR therefore includes &lt;strong&gt;CRC-32 integrity verification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The simplified pipeline looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payload
↓
Header + CRC-32
↓
Reed-Solomon ECC
↓
Interleaving
↓
RGBW encoding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During decoding, the process runs in reverse.&lt;/p&gt;

&lt;p&gt;The CRC gives the decoder a final acceptance check rather than blindly returning bytes after an uncertain recovery.&lt;/p&gt;




&lt;h2&gt;
  
  
  But error correction is not encryption
&lt;/h2&gt;

&lt;p&gt;This is an important distinction.&lt;/p&gt;

&lt;p&gt;A QR-like symbol can have excellent error correction while offering &lt;strong&gt;zero confidentiality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Anyone with a compatible decoder can read a normal payload.&lt;/p&gt;

&lt;p&gt;CRC protects against accidental corruption.&lt;/p&gt;

&lt;p&gt;Reed-Solomon protects against physical or transmission errors.&lt;/p&gt;

&lt;p&gt;Neither prevents someone from reading the data.&lt;/p&gt;

&lt;p&gt;So I added a separate security layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secure Payload v1
&lt;/h2&gt;

&lt;p&gt;QuadQR now supports optional &lt;strong&gt;authenticated encryption&lt;/strong&gt; directly at the payload layer.&lt;/p&gt;

&lt;p&gt;The feature is called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secure Payload v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It intentionally sits above the matrix codec.&lt;/p&gt;

&lt;p&gt;That means encryption does not require another type of QuadQR geometry.&lt;/p&gt;

&lt;p&gt;The same:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RGBW encoding&lt;/li&gt;
&lt;li&gt;scanner&lt;/li&gt;
&lt;li&gt;Spectrum ECC&lt;/li&gt;
&lt;li&gt;Reed-Solomon layer&lt;/li&gt;
&lt;li&gt;perspective correction&lt;/li&gt;
&lt;li&gt;rendering pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;continues to work.&lt;/p&gt;

&lt;p&gt;Only the payload being encoded changes.&lt;/p&gt;

&lt;p&gt;The secure pipeline becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plaintext
↓
Secure Payload v1
↓
AES-256-GCM ciphertext
↓
QuadQR framing + CRC
↓
Reed-Solomon
↓
Spectral-spatial interleaving
↓
RGBW matrix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security is &lt;strong&gt;optional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Normal unencrypted QuadQR remains the default.&lt;/p&gt;




&lt;h2&gt;
  
  
  AES-256-GCM
&lt;/h2&gt;

&lt;p&gt;Secure Payload v1 uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AES-256-GCM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GCM is important because it provides both:&lt;/p&gt;

&lt;h3&gt;
  
  
  Confidentiality
&lt;/h3&gt;

&lt;p&gt;Someone scanning the symbol without the correct secret cannot read the plaintext.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;If the encrypted payload has been modified, decryption should fail authentication instead of quietly returning corrupted plaintext.&lt;/p&gt;

&lt;p&gt;That means Secure Payload is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;encrypt(data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is authenticated encryption.&lt;/p&gt;

&lt;p&gt;A wrong secret or altered ciphertext does not produce a successful trusted decode.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two security modes
&lt;/h2&gt;

&lt;p&gt;QuadQR currently supports two ways to protect a payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Password mode
&lt;/h3&gt;

&lt;p&gt;For cases where humans need to exchange a protected QuadQR, you can encrypt using a password.&lt;/p&gt;

&lt;p&gt;The password is not used directly as the AES key.&lt;/p&gt;

&lt;p&gt;Instead QuadQR derives a 256-bit key using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PBKDF2-HMAC-SHA-256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current default uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;600,000 iterations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a randomly generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;16-byte salt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So two encryptions of the same content using the same password do not simply reuse an identical derived-key context.&lt;/p&gt;

&lt;p&gt;This mode is useful for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;privately shared information&lt;/li&gt;
&lt;li&gt;protected notes&lt;/li&gt;
&lt;li&gt;credentials exchanged through another trusted channel&lt;/li&gt;
&lt;li&gt;configuration payloads&lt;/li&gt;
&lt;li&gt;human-readable secure transfers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The password itself is &lt;strong&gt;not stored inside the QuadQR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That would defeat the purpose.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Raw 256-bit key mode
&lt;/h3&gt;

&lt;p&gt;Applications often should not rely on human passwords at all.&lt;/p&gt;

&lt;p&gt;So QuadQR also supports an exact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;32-byte / 256-bit key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;supplied by the application.&lt;/p&gt;

&lt;p&gt;This is more appropriate for use cases such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provisioning&lt;/li&gt;
&lt;li&gt;enterprise scanners&lt;/li&gt;
&lt;li&gt;device pairing systems&lt;/li&gt;
&lt;li&gt;tickets&lt;/li&gt;
&lt;li&gt;internal applications&lt;/li&gt;
&lt;li&gt;secure workflows&lt;/li&gt;
&lt;li&gt;application-to-application transfer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The secret raw key is never embedded inside the QuadQR.&lt;/p&gt;

&lt;p&gt;Instead, QuadQR can include a small &lt;strong&gt;non-secret key identifier&lt;/strong&gt; derived from the key.&lt;/p&gt;

&lt;p&gt;By default this is an 8-byte fingerprint based on SHA-256.&lt;/p&gt;

&lt;p&gt;That lets an application determine something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This QR expects key ID ABC123...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without exposing the actual encryption key.&lt;/p&gt;

&lt;p&gt;The application can then select the matching secret from its own secure key store.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why the security envelope is versioned
&lt;/h2&gt;

&lt;p&gt;Cryptographic formats need room to evolve.&lt;/p&gt;

&lt;p&gt;I did not want the entire QuadQR matrix format tied forever to one specific KDF or encryption structure.&lt;/p&gt;

&lt;p&gt;So Secure Payload has its own versioning.&lt;/p&gt;

&lt;p&gt;Today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secure Payload v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can use AES-256-GCM and the currently defined key derivation modes.&lt;/p&gt;

&lt;p&gt;A future security envelope could introduce something different without requiring a redesign of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RGBW
finder patterns
ECC
interleaving
matrix geometry
scanner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping cryptographic framing separate from physical encoding makes the architecture much cleaner.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secure codes work with both scanners
&lt;/h2&gt;

&lt;p&gt;Security is integrated into the decoding flow rather than being an unrelated utility.&lt;/p&gt;

&lt;p&gt;When the image scanner or camera scanner finds an encrypted QuadQR, it recognizes the secure envelope.&lt;/p&gt;

&lt;p&gt;But it does &lt;strong&gt;not&lt;/strong&gt; immediately expose plaintext.&lt;/p&gt;

&lt;p&gt;Instead, the decoded result indicates that decryption is required.&lt;/p&gt;

&lt;p&gt;The user or application provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and authenticated decryption is then attempted.&lt;/p&gt;

&lt;p&gt;For the live camera scanner, once the secure code is successfully detected, the application can stop scanning and move into the decryption flow.&lt;/p&gt;

&lt;p&gt;So the camera does not need to know the password before it can locate and decode the physical QuadQR.&lt;/p&gt;

&lt;p&gt;It first reconstructs the encrypted payload.&lt;/p&gt;

&lt;p&gt;Then the security layer handles decryption.&lt;/p&gt;




&lt;h2&gt;
  
  
  How much more data can QuadQR store?
&lt;/h2&gt;

&lt;p&gt;This is where I want to be very careful.&lt;/p&gt;

&lt;p&gt;At the raw data-cell level, the answer is mathematically straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional binary data cell = 1 bit
QuadQR RGBW data cell         = 2 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the &lt;strong&gt;raw alphabet density is exactly 2x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But real barcode capacity is not determined only by bits per module.&lt;/p&gt;

&lt;p&gt;Both formats reserve space for things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;positioning&lt;/li&gt;
&lt;li&gt;timing&lt;/li&gt;
&lt;li&gt;alignment&lt;/li&gt;
&lt;li&gt;metadata&lt;/li&gt;
&lt;li&gt;masking&lt;/li&gt;
&lt;li&gt;error correction&lt;/li&gt;
&lt;li&gt;framing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;QuadQR additionally needs color calibration.&lt;/p&gt;

&lt;p&gt;So I built a benchmark instead of claiming that every QuadQR simply stores exactly twice as much data.&lt;/p&gt;

&lt;p&gt;The current representative results using the project's &lt;code&gt;M&lt;/code&gt; profile are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Matrix&lt;/th&gt;
&lt;th&gt;QuadQR&lt;/th&gt;
&lt;th&gt;Standard QR reference&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;21×21&lt;/td&gt;
&lt;td&gt;24 B&lt;/td&gt;
&lt;td&gt;14 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.71x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;25×25&lt;/td&gt;
&lt;td&gt;48 B&lt;/td&gt;
&lt;td&gt;26 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.85x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;37×37&lt;/td&gt;
&lt;td&gt;227 B&lt;/td&gt;
&lt;td&gt;84 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.70x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;57×57&lt;/td&gt;
&lt;td&gt;630 B&lt;/td&gt;
&lt;td&gt;213 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.96x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;97×97&lt;/td&gt;
&lt;td&gt;1992 B&lt;/td&gt;
&lt;td&gt;666 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.99x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;137×137&lt;/td&gt;
&lt;td&gt;4054 B&lt;/td&gt;
&lt;td&gt;1370 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.96x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;177×177&lt;/td&gt;
&lt;td&gt;6858 B&lt;/td&gt;
&lt;td&gt;2331 B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.94x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Version 10
Matrix: 57 × 57

QuadQR:             630 bytes
Standard reference: 213 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is approximately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.96x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;usable payload capacity in the current same-dimension benchmark.&lt;/p&gt;

&lt;p&gt;But there is an extremely important caveat.&lt;/p&gt;




&lt;h2&gt;
  
  
  A 2.96x capacity ratio does NOT mean QuadQR is 2.96x better
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;L&lt;/code&gt;, &lt;code&gt;M&lt;/code&gt;, &lt;code&gt;Q&lt;/code&gt;, and &lt;code&gt;H&lt;/code&gt; profiles in QuadQR are &lt;strong&gt;project-defined profiles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They currently do not claim the same standardized physical damage recovery percentages as the corresponding ISO QR Code error correction levels.&lt;/p&gt;

&lt;p&gt;So this benchmark means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Same matrix dimensions and same ECC label.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; yet mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Same dimensions and independently proven identical real-world damage tolerance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are different experiments.&lt;/p&gt;

&lt;p&gt;The ratios approaching 3x also do not mean each QuadQR module somehow stores 3 bits.&lt;/p&gt;

&lt;p&gt;It does not.&lt;/p&gt;

&lt;p&gt;Every QuadQR data cell still stores exactly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The additional difference comes from how the two formats allocate structural, framing, and ECC overhead.&lt;/p&gt;

&lt;p&gt;One of the major future benchmarks I want to build is an &lt;strong&gt;equal-reliability comparison&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That would expose QuadQR and traditional QR Codes to comparable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blur&lt;/li&gt;
&lt;li&gt;noise&lt;/li&gt;
&lt;li&gt;shadows&lt;/li&gt;
&lt;li&gt;scratches&lt;/li&gt;
&lt;li&gt;JPEG artifacts&lt;/li&gt;
&lt;li&gt;perspective distortion&lt;/li&gt;
&lt;li&gt;low light&lt;/li&gt;
&lt;li&gt;glare&lt;/li&gt;
&lt;li&gt;partial obstruction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and compare capacity only after both formats achieve similar decode success rates.&lt;/p&gt;

&lt;p&gt;That will be a much more meaningful comparison.&lt;/p&gt;




&lt;h2&gt;
  
  
  Version 1 needed special treatment
&lt;/h2&gt;

&lt;p&gt;Small symbols are surprisingly difficult.&lt;/p&gt;

&lt;p&gt;At a 21×21 matrix, fixed structural metadata occupies a much larger percentage of the available cells.&lt;/p&gt;

&lt;p&gt;The original QuadQR framing was simply too expensive for a useful Version 1 symbol at the project's &lt;code&gt;M&lt;/code&gt; profile.&lt;/p&gt;

&lt;p&gt;So Version 1 now has a dedicated compact profile.&lt;/p&gt;

&lt;p&gt;At &lt;code&gt;M&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;21×21 QuadQR
24 bytes payload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while the standard QR byte-mode reference at the same dimensions is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;14 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Versions 2 and above use the normal QuadQR framing structure.&lt;/p&gt;

&lt;p&gt;It was a good reminder that theoretical density is only the beginning.&lt;/p&gt;

&lt;p&gt;Format overhead matters enormously at small sizes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Safe visual styling without changing the format
&lt;/h2&gt;

&lt;p&gt;Once the scanner was working, I also wanted QuadQR to look a little less mechanical.&lt;/p&gt;

&lt;p&gt;But styling machine-readable codes can be dangerous.&lt;/p&gt;

&lt;p&gt;Effects like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;heavy shadows&lt;/li&gt;
&lt;li&gt;gradients&lt;/li&gt;
&lt;li&gt;transparency&lt;/li&gt;
&lt;li&gt;random colors&lt;/li&gt;
&lt;li&gt;distorted finder patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can quickly destroy scan reliability.&lt;/p&gt;

&lt;p&gt;So QuadQR keeps visual rendering completely separate from the encoded matrix.&lt;/p&gt;

&lt;p&gt;It currently provides four rendering styles:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;classic&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Solid square modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;depth&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Subtle deterministic fading and edge treatment creates more visual depth while preserving encoded colors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;soft&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Rounded payload modules create a softer appearance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;inset&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Adds a recessed edge treatment while preserving the exact encoded RGBW color around the center of the module.&lt;/p&gt;

&lt;p&gt;Usage looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;renderToCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;moduleSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;quietZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical structural elements remain solid and square:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finder patterns&lt;/li&gt;
&lt;li&gt;timing structures&lt;/li&gt;
&lt;li&gt;alignment markers&lt;/li&gt;
&lt;li&gt;calibration cells&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scanner primarily samples the center area of data modules, so styles are designed around preserving that encoded center.&lt;/p&gt;

&lt;p&gt;The styles are also deterministic.&lt;/p&gt;

&lt;p&gt;Generating the same QuadQR with the same style produces the same visual result instead of randomly changing modules every time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using QuadQR from JavaScript
&lt;/h2&gt;

&lt;p&gt;QuadQR is now available on npm as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;quadqr-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;encodeText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;decodeMatrix&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quadqr-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encodeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from QuadQR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ecc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeMatrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library includes APIs for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text encoding&lt;/li&gt;
&lt;li&gt;binary encoding&lt;/li&gt;
&lt;li&gt;matrix decoding&lt;/li&gt;
&lt;li&gt;canvas rendering&lt;/li&gt;
&lt;li&gt;ImageData rendering&lt;/li&gt;
&lt;li&gt;image scanning&lt;/li&gt;
&lt;li&gt;video-frame scanning&lt;/li&gt;
&lt;li&gt;live camera scanning&lt;/li&gt;
&lt;li&gt;version/capacity inspection&lt;/li&gt;
&lt;li&gt;secure payload handling&lt;/li&gt;
&lt;li&gt;benchmarking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can be used in browser and Node.js environments.&lt;/p&gt;

&lt;p&gt;The package also includes TypeScript declarations for consumers even though the project itself is JavaScript-focused.&lt;/p&gt;




&lt;h2&gt;
  
  
  There is a CLI too
&lt;/h2&gt;

&lt;p&gt;You can generate a QuadQR directly from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx quadqr-js encode &lt;span class="s2"&gt;"Hello QuadQR"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; hello.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And decode it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx quadqr-js decode hello.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secure payloads work from the CLI as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx quadqr-js encode &lt;span class="s2"&gt;"Private data"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--password&lt;/span&gt; &lt;span class="s2"&gt;"my-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; secure.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx quadqr-js decode secure.png &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--password&lt;/span&gt; &lt;span class="s2"&gt;"my-password"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Raw 256-bit key mode is supported too.&lt;/p&gt;

&lt;p&gt;This makes QuadQR usable outside the demo application and also makes automated testing much easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser, Node, CDN, and WASM packaging
&lt;/h2&gt;

&lt;p&gt;I wanted the project to be more than a demo page.&lt;/p&gt;

&lt;p&gt;The npm package currently exposes builds for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ES modules
CommonJS
Browser
Node.js
CDN usage
Benchmark utilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So applications do not have to copy pieces from the repository manually.&lt;/p&gt;

&lt;p&gt;The package is currently published as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;quadqr-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;A format like this is very easy to make work for one perfectly generated image.&lt;/p&gt;

&lt;p&gt;That is not enough.&lt;/p&gt;

&lt;p&gt;The current test suite covers areas including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RGBW mapping&lt;/li&gt;
&lt;li&gt;binary round trips&lt;/li&gt;
&lt;li&gt;Unicode text&lt;/li&gt;
&lt;li&gt;version selection&lt;/li&gt;
&lt;li&gt;capacity boundaries&lt;/li&gt;
&lt;li&gt;all ECC profiles&lt;/li&gt;
&lt;li&gt;Reed-Solomon corruption recovery&lt;/li&gt;
&lt;li&gt;Spectrum ECC behavior&lt;/li&gt;
&lt;li&gt;image scanning&lt;/li&gt;
&lt;li&gt;rotation&lt;/li&gt;
&lt;li&gt;perspective distortion&lt;/li&gt;
&lt;li&gt;color casts&lt;/li&gt;
&lt;li&gt;secure payload encryption/decryption&lt;/li&gt;
&lt;li&gt;package distribution&lt;/li&gt;
&lt;li&gt;benchmark reference data&lt;/li&gt;
&lt;li&gt;codec performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is still significantly more real-device testing to do, especially across different cameras, printers, papers, lighting conditions, and display technologies.&lt;/p&gt;




&lt;h2&gt;
  
  
  QuadQR is not a replacement for QR Code
&lt;/h2&gt;

&lt;p&gt;This is probably the most important part of this article.&lt;/p&gt;

&lt;p&gt;QuadQR is &lt;strong&gt;experimental&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is not an ISO QR Code.&lt;/p&gt;

&lt;p&gt;A normal phone QR scanner cannot decode it.&lt;/p&gt;

&lt;p&gt;Traditional QR Code has enormous advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;decades of deployment&lt;/li&gt;
&lt;li&gt;ISO standardization&lt;/li&gt;
&lt;li&gt;billions of compatible devices&lt;/li&gt;
&lt;li&gt;highly optimized decoders&lt;/li&gt;
&lt;li&gt;proven print behavior&lt;/li&gt;
&lt;li&gt;mature error correction&lt;/li&gt;
&lt;li&gt;enormous real-world datasets&lt;/li&gt;
&lt;li&gt;extensive interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would not currently recommend replacing a production-critical QR workflow with QuadQR.&lt;/p&gt;

&lt;p&gt;That is not what this project is claiming.&lt;/p&gt;

&lt;p&gt;The question I am exploring is different:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If we were designing a QR-inspired matrix code around modern color-capable cameras and displays today, what could we do differently?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;QuadQR is my attempt to explore that question through actual code rather than just theory.&lt;/p&gt;




&lt;h2&gt;
  
  
  There are still hard problems
&lt;/h2&gt;

&lt;p&gt;Color gives us more information, but it also introduces an entirely new class of problems.&lt;/p&gt;

&lt;p&gt;Some of the things I still want to investigate deeply are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;different printer and ink combinations&lt;/li&gt;
&lt;li&gt;colored or reflective paper&lt;/li&gt;
&lt;li&gt;OLED vs LCD displays&lt;/li&gt;
&lt;li&gt;screen brightness&lt;/li&gt;
&lt;li&gt;camera white balance&lt;/li&gt;
&lt;li&gt;extreme shadows&lt;/li&gt;
&lt;li&gt;low-light conditions&lt;/li&gt;
&lt;li&gt;motion blur&lt;/li&gt;
&lt;li&gt;display moiré&lt;/li&gt;
&lt;li&gt;glare&lt;/li&gt;
&lt;li&gt;color-blind camera processing&lt;/li&gt;
&lt;li&gt;very small module sizes&lt;/li&gt;
&lt;li&gt;extreme viewing angles&lt;/li&gt;
&lt;li&gt;physical scratches&lt;/li&gt;
&lt;li&gt;partially hidden symbols&lt;/li&gt;
&lt;li&gt;RGBW confusion matrices&lt;/li&gt;
&lt;li&gt;large-symbol alignment&lt;/li&gt;
&lt;li&gt;print-quality grading&lt;/li&gt;
&lt;li&gt;cross-device scanning performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a big difference between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"It works on my phone."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"We understand the statistical reliability of this format."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second one is much harder.&lt;/p&gt;

&lt;p&gt;And much more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I want to build next
&lt;/h2&gt;

&lt;p&gt;There are several directions I want to continue exploring.&lt;/p&gt;

&lt;p&gt;The biggest one is an automated torture-test system.&lt;/p&gt;

&lt;p&gt;I want to generate QuadQR symbols and programmatically apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blur
noise
perspective distortion
JPEG compression
shadows
brightness changes
color shifts
occlusion
glare simulation
scaling
rotation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then measure exactly where decoding succeeds and fails.&lt;/p&gt;

&lt;p&gt;After that, physical testing matters even more.&lt;/p&gt;

&lt;p&gt;Generate.&lt;/p&gt;

&lt;p&gt;Print.&lt;/p&gt;

&lt;p&gt;Damage.&lt;/p&gt;

&lt;p&gt;Photograph.&lt;/p&gt;

&lt;p&gt;Scan.&lt;/p&gt;

&lt;p&gt;Repeat across devices.&lt;/p&gt;

&lt;p&gt;That data can then guide improvements to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;calibration&lt;/li&gt;
&lt;li&gt;Spectrum ECC&lt;/li&gt;
&lt;li&gt;erasure selection&lt;/li&gt;
&lt;li&gt;alignment strategies&lt;/li&gt;
&lt;li&gt;interleaving&lt;/li&gt;
&lt;li&gt;color classification&lt;/li&gt;
&lt;li&gt;version selection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;instead of relying on guesses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I made it open source
&lt;/h2&gt;

&lt;p&gt;A new matrix-code format is much more interesting when other people can inspect it, break it, test it, and challenge the assumptions behind it.&lt;/p&gt;

&lt;p&gt;The project includes documentation for the format itself, not just the library API.&lt;/p&gt;

&lt;p&gt;So if someone wants to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspect the encoding&lt;/li&gt;
&lt;li&gt;build another decoder&lt;/li&gt;
&lt;li&gt;test the ECC&lt;/li&gt;
&lt;li&gt;improve the scanner&lt;/li&gt;
&lt;li&gt;benchmark another camera&lt;/li&gt;
&lt;li&gt;investigate color classification&lt;/li&gt;
&lt;li&gt;find a flaw in the format&lt;/li&gt;
&lt;li&gt;experiment with another implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;they can.&lt;/p&gt;

&lt;p&gt;QuadQR is licensed under &lt;strong&gt;AGPL-3.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Contributions, experiments, test images, benchmarks, scanner improvements, and criticism are all welcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI helped me build parts of it
&lt;/h2&gt;

&lt;p&gt;One other thing I want to be transparent about.&lt;/p&gt;

&lt;p&gt;I designed the idea, researched the architecture, made the format decisions, tested the behavior, and iterated on the project.&lt;/p&gt;

&lt;p&gt;I also used &lt;strong&gt;OpenAI Codex as a pair-programming tool&lt;/strong&gt; during development.&lt;/p&gt;

&lt;p&gt;It was particularly useful while working through some of the more complex implementation areas, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;codec work&lt;/li&gt;
&lt;li&gt;Reed-Solomon logic&lt;/li&gt;
&lt;li&gt;scanner/image-processing code&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;optimizations&lt;/li&gt;
&lt;li&gt;repetitive implementation tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think projects like this are also a good example of where AI-assisted development becomes interesting.&lt;/p&gt;

&lt;p&gt;The hard part is not asking an AI to "make a QR code."&lt;/p&gt;

&lt;p&gt;The hard part is repeatedly asking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Does this design actually make sense?

What fails when lighting changes?

Are these benchmarks fair?

What happens when the color decision is uncertain?

Can the ECC use that uncertainty?

Does adding another color really help?

Does this visual effect reduce scanning reliability?

Are we measuring capacity or actual robustness?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI can accelerate implementation enormously.&lt;/p&gt;

&lt;p&gt;But engineering decisions, experiments, skepticism, and validation still matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try QuadQR yourself
&lt;/h2&gt;

&lt;p&gt;You do not need to install anything to experiment with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Demo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://akanshsirohi.github.io/QuadQR/demo/" rel="noopener noreferrer"&gt;https://akanshsirohi.github.io/QuadQR/demo/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate QuadQR symbols&lt;/li&gt;
&lt;li&gt;choose ECC profiles&lt;/li&gt;
&lt;li&gt;try different rendering styles&lt;/li&gt;
&lt;li&gt;scan image files&lt;/li&gt;
&lt;li&gt;scan using your camera&lt;/li&gt;
&lt;li&gt;create secure encrypted symbols&lt;/li&gt;
&lt;li&gt;test password-protected payloads&lt;/li&gt;
&lt;li&gt;view capacity comparisons&lt;/li&gt;
&lt;li&gt;explore benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://akanshsirohi.github.io/QuadQR/docs-site/" rel="noopener noreferrer"&gt;https://akanshsirohi.github.io/QuadQR/docs-site/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/akanshSirohi/QuadQR" rel="noopener noreferrer"&gt;https://github.com/akanshSirohi/QuadQR&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  npm
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;quadqr-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.npmjs.com/package/quadqr-js" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/quadqr-js&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;QuadQR started from one small question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why should every visible data cell still be binary?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question turned into a much larger experiment involving:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;color theory
matrix encoding
computer vision
perspective geometry
Reed-Solomon coding
erasure decoding
interleaving
cryptography
camera processing
benchmarking
browser APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there is still a lot to learn.&lt;/p&gt;

&lt;p&gt;Four colors give each QuadQR data cell exactly two bits of raw information.&lt;/p&gt;

&lt;p&gt;But making those four colors &lt;strong&gt;reliably recoverable from a real camera&lt;/strong&gt; is where the real engineering begins.&lt;/p&gt;

&lt;p&gt;Adding Spectrum ECC made the scanner capable of using its uncertainty instead of ignoring it.&lt;/p&gt;

&lt;p&gt;Spectral-spatial interleaving made localized physical damage less concentrated.&lt;/p&gt;

&lt;p&gt;Secure Payload v1 added optional AES-256-GCM authenticated encryption without changing the physical code format.&lt;/p&gt;

&lt;p&gt;And publishing the entire thing as an open-source JavaScript library means other developers can now experiment with it too.&lt;/p&gt;

&lt;p&gt;I do not know whether color matrix codes will ever become as universally practical as traditional QR Code.&lt;/p&gt;

&lt;p&gt;But I think the question is worth exploring.&lt;/p&gt;

&lt;p&gt;And that is exactly what QuadQR is for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you work with computer vision, error-correcting codes, cryptography, barcode systems, or image processing, I would genuinely love to hear what you would test, break, or improve first.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/akanshSirohi/QuadQR" rel="noopener noreferrer"&gt;https://github.com/akanshSirohi/QuadQR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://akanshsirohi.github.io/QuadQR/demo/" rel="noopener noreferrer"&gt;https://akanshsirohi.github.io/QuadQR/demo/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm:&lt;/strong&gt; &lt;code&gt;quadqr-js&lt;/code&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>news</category>
    </item>
    <item>
      <title>I Built PromptVault to Solve My Prompt Management Mess, and It Turned Into a Full Offline-First AI Prompt Workspace</title>
      <dc:creator>Akansh Sirohi</dc:creator>
      <pubDate>Sun, 12 Apr 2026 07:15:56 +0000</pubDate>
      <link>https://dev.to/akanshsirohi/i-built-promptvault-to-solve-my-prompt-management-mess-and-it-turned-into-a-full-offline-first-ai-2ejm</link>
      <guid>https://dev.to/akanshsirohi/i-built-promptvault-to-solve-my-prompt-management-mess-and-it-turned-into-a-full-offline-first-ai-2ejm</guid>
      <description>&lt;p&gt;If you use AI tools regularly, you probably already know the problem.&lt;/p&gt;

&lt;p&gt;Prompts end up everywhere.&lt;/p&gt;

&lt;p&gt;Some are in notes apps. Some are buried inside chats. Some are saved in random text files. A few good ones get reused, but most disappear the moment you actually need them again.&lt;/p&gt;

&lt;p&gt;That frustration is what pushed me to build &lt;strong&gt;PromptVault&lt;/strong&gt;, an Android app focused on capturing, organizing, reusing, and experimenting with prompts in a more structured way.&lt;/p&gt;

&lt;p&gt;At first, I just wanted a better way to save prompts.&lt;/p&gt;

&lt;p&gt;But while building it, I realized the real problem was bigger than storage.&lt;/p&gt;

&lt;p&gt;People do not just &lt;em&gt;save&lt;/em&gt; prompts anymore. They refine them, organize them, test them, reuse them with variables, convert them into structured formats, sync them, share them, and increasingly want to use them across devices.&lt;/p&gt;

&lt;p&gt;So PromptVault gradually became more than a prompt notes app. It turned into a more complete prompt workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  What PromptVault is
&lt;/h2&gt;

&lt;p&gt;PromptVault is an &lt;strong&gt;offline-first Android app&lt;/strong&gt; for managing AI prompts.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capture prompts quickly&lt;/li&gt;
&lt;li&gt;Organize them properly&lt;/li&gt;
&lt;li&gt;Reuse them without rewriting everything&lt;/li&gt;
&lt;li&gt;Support both plain-text and structured prompt workflows&lt;/li&gt;
&lt;li&gt;Keep the experience useful even without forcing sign-in or cloud dependency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last part mattered a lot to me.&lt;/p&gt;

&lt;p&gt;I did not want the app to become one of those tools that feels unusable until you create an account, connect a service, and stay online all the time. So I designed it to work locally first, with cloud features available when the user actually wants them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I wanted to solve
&lt;/h2&gt;

&lt;p&gt;A lot of people working with AI still manage prompts in pretty chaotic ways.&lt;/p&gt;

&lt;p&gt;A common workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save a prompt in a note&lt;/li&gt;
&lt;li&gt;Copy it into ChatGPT or another AI tool&lt;/li&gt;
&lt;li&gt;Edit it slightly for a new use case&lt;/li&gt;
&lt;li&gt;Forget where the original version was&lt;/li&gt;
&lt;li&gt;Repeat the same process next week&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That works for a while, but it breaks down fast when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have many prompts&lt;/li&gt;
&lt;li&gt;you need categories or tags&lt;/li&gt;
&lt;li&gt;you want reusable variables&lt;/li&gt;
&lt;li&gt;you are testing prompt variants&lt;/li&gt;
&lt;li&gt;you want JSON-based or structured prompts for apps and agents&lt;/li&gt;
&lt;li&gt;you want to access prompts from another device&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something that handled these realities properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core features I built into PromptVault
&lt;/h2&gt;

&lt;p&gt;Here are some of the features that make PromptVault actually useful in day-to-day workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Offline-first usage
&lt;/h3&gt;

&lt;p&gt;Users can continue without signing in and still use the app locally.&lt;/p&gt;

&lt;p&gt;That means PromptVault works even if someone just wants a private local prompt library. If they later decide to sign in, the app can handle that transition more cleanly.&lt;/p&gt;

&lt;p&gt;This was a deliberate design choice because I wanted the app to be useful from the first launch, not after account setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prompt library with proper organization
&lt;/h3&gt;

&lt;p&gt;Prompts are not just stored as raw text.&lt;/p&gt;

&lt;p&gt;Each prompt can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;content preview&lt;/li&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;li&gt;collection assignment&lt;/li&gt;
&lt;li&gt;favorite state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users can create, edit, clone, delete, and favorite prompts, and there is a dedicated favorites view as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Variables and reusable prompt templates
&lt;/h3&gt;

&lt;p&gt;One of the most useful parts of working with prompts is reusability.&lt;/p&gt;

&lt;p&gt;Instead of rewriting similar prompts again and again, PromptVault supports variable-based prompts where placeholders can be filled dynamically.&lt;/p&gt;

&lt;p&gt;That makes it much easier to turn one good prompt into something reusable for multiple contexts.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Dual editing modes: normal and JSON
&lt;/h3&gt;

&lt;p&gt;This is one of the features I personally find most interesting.&lt;/p&gt;

&lt;p&gt;PromptVault supports both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;standard text prompt editing&lt;/li&gt;
&lt;li&gt;JSON prompt editing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For JSON prompts, I added both a &lt;strong&gt;visual builder&lt;/strong&gt; and a &lt;strong&gt;code editor mode&lt;/strong&gt;. That makes the app more useful not only for casual users, but also for developers building structured prompt workflows, AI tools, or agent-like systems.&lt;/p&gt;

&lt;p&gt;There are also helper features like formatting, syntax-friendly editing, variable insertion, and preview/copy tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. AI-assisted prompt editing and AI Prompt Creator
&lt;/h3&gt;

&lt;p&gt;PromptVault also includes AI-assisted actions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generating a title&lt;/li&gt;
&lt;li&gt;generating a description&lt;/li&gt;
&lt;li&gt;optimizing a prompt body&lt;/li&gt;
&lt;li&gt;writing a prompt from a short brief&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of that, one of the newer additions is an &lt;strong&gt;AI Prompt Creator&lt;/strong&gt; feature.&lt;/p&gt;

&lt;p&gt;Instead of starting from a blank screen, users can describe what kind of prompt they want, and the app helps generate a usable prompt draft that can then be saved, edited, refined, or organized inside their collection.&lt;/p&gt;

&lt;p&gt;I like this feature because it makes the app useful not only for storing good prompts, but also for helping users create better ones faster.&lt;/p&gt;

&lt;p&gt;These AI features are not meant to replace the user’s thinking. They are there to reduce friction when refining, expanding, or generating prompts more efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Chat workspace with prompt-aware assistance
&lt;/h3&gt;

&lt;p&gt;I also added a dedicated chat area with local session history and support for multiple sessions.&lt;/p&gt;

&lt;p&gt;Users can configure sessions with their own model, system prompt, and history-message limit. That makes the app feel more like a practical workspace rather than just a storage utility.&lt;/p&gt;

&lt;p&gt;One of the newer things I added here is &lt;strong&gt;RAG-style prompt retrieval inside chat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means the chat experience can surface relevant prompts from the user’s own collection as suggestions or context, instead of treating the prompt library and chat workspace as two completely separate parts of the app.&lt;/p&gt;

&lt;p&gt;I think this is especially useful because once you build up a real prompt library, the next challenge is not just storing prompts. It is being able to actually &lt;em&gt;find and reuse the right one at the right time&lt;/em&gt; while chatting or testing ideas.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. PromptVault Web
&lt;/h3&gt;

&lt;p&gt;One feature I really liked building was &lt;strong&gt;PromptVault Web&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The app can host a local web interface from the Android device itself, allowing prompts to be accessed from another device on the same network.&lt;/p&gt;

&lt;p&gt;That means a user can manage prompts from their phone and then open them on a PC or another screen without needing a conventional hosted web backend for that use case.&lt;/p&gt;

&lt;p&gt;I found that direction especially interesting because it opens up a very practical bridge between mobile-first and desktop usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Backup and sync options
&lt;/h3&gt;

&lt;p&gt;PromptVault supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local encrypted backup export/import&lt;/li&gt;
&lt;li&gt;Google Drive backup and restore&lt;/li&gt;
&lt;li&gt;optional cloud sync when signed in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, I wanted flexibility here rather than forcing a single storage model.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. On-device model support and cloud options
&lt;/h3&gt;

&lt;p&gt;The app supports two AI provider directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on-device model support&lt;/li&gt;
&lt;li&gt;Ollama Cloud support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That split was important because different users want different things. Some care more about local control and privacy. Others want convenience and cloud-based access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I made it offline-first
&lt;/h2&gt;

&lt;p&gt;Offline-first design was not just a technical preference. It shaped the product itself.&lt;/p&gt;

&lt;p&gt;When you treat local usage as a first-class experience, you naturally design differently.&lt;/p&gt;

&lt;p&gt;You start asking questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What should still work without sign-in?&lt;/li&gt;
&lt;li&gt;What should remain useful without internet?&lt;/li&gt;
&lt;li&gt;How do you handle local-to-cloud transitions safely?&lt;/li&gt;
&lt;li&gt;How do you avoid making cloud dependence feel mandatory?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That led to design decisions around local storage, pending sync behavior, backup options, session handling, and feature gating.&lt;/p&gt;

&lt;p&gt;I think more apps should take this approach where possible, especially productivity tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned while building it
&lt;/h2&gt;

&lt;p&gt;A few things became very clear during development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good prompt tools need structure
&lt;/h3&gt;

&lt;p&gt;People do not just want a text box. They want organization, grouping, variables, search, filters, and reusable patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline support changes product quality
&lt;/h3&gt;

&lt;p&gt;When local usage is treated seriously, the app feels more dependable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt workflows are becoming more technical
&lt;/h3&gt;

&lt;p&gt;As more developers work with agents, automation, and structured AI workflows, support for JSON and reusable schemas becomes much more valuable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-device access matters a lot
&lt;/h3&gt;

&lt;p&gt;Even if an app starts on mobile, users still want to use their data on a laptop, desktop, or another device nearby.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m sharing this
&lt;/h2&gt;

&lt;p&gt;I wanted to share PromptVault because I think prompt management is still a messy area for a lot of people, especially developers, builders, and regular AI users who are starting to accumulate prompt libraries.&lt;/p&gt;

&lt;p&gt;There are plenty of AI apps focused on generation, but not as many tools focused on &lt;strong&gt;managing the prompts themselves well&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This project started as a practical problem I wanted to solve for myself, and it slowly turned into something broader and more useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  I’d love feedback
&lt;/h2&gt;

&lt;p&gt;If you’ve built anything in the AI tooling space, I’d genuinely love to know how you think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompt storage&lt;/li&gt;
&lt;li&gt;prompt reusability&lt;/li&gt;
&lt;li&gt;structured prompt formats&lt;/li&gt;
&lt;li&gt;offline-first productivity apps&lt;/li&gt;
&lt;li&gt;local-first or hybrid sync models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you use AI heavily, I’d be curious to know how you currently manage your prompts, because I suspect most people are still piecing together their own system.&lt;/p&gt;




&lt;p&gt;I built PromptVault as a way to make prompt work more organized, reusable, and practical.&lt;/p&gt;

&lt;p&gt;If you’ve ever lost a great prompt in a sea of notes, chats, and screenshots, you probably understand exactly why I made it.&lt;/p&gt;

&lt;p&gt;PromptVault is currently available on &lt;strong&gt;Android&lt;/strong&gt;, and one thing I cared about from the beginning was keeping it &lt;strong&gt;ad-free&lt;/strong&gt; so the experience stays focused and distraction-free.&lt;/p&gt;

&lt;p&gt;You can check it out here: &lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.akansh.promptvault" rel="noopener noreferrer"&gt;Download PromptVault on Google Play&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.akansh.promptvault" rel="noopener noreferrer"&gt;&lt;br&gt;
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fplay.google.com%2Fintl%2Fen_us%2Fbadges%2Fstatic%2Fimages%2Fbadges%2Fen_badge_web_generic.png" width="646" height="250"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Introducing GitHub Cards API: A simple way to create beautiful cards with random quotes and jokes</title>
      <dc:creator>Akansh Sirohi</dc:creator>
      <pubDate>Wed, 11 Oct 2023 16:52:34 +0000</pubDate>
      <link>https://dev.to/akanshsirohi/introducing-github-cards-api-a-simple-way-to-create-beautiful-cards-with-random-quotes-and-jokes-467n</link>
      <guid>https://dev.to/akanshsirohi/introducing-github-cards-api-a-simple-way-to-create-beautiful-cards-with-random-quotes-and-jokes-467n</guid>
      <description>&lt;p&gt;Do you like to add some humor and inspiration to your GitHub profile or website? Do you want to display some random quotes and jokes with different themes and colors? If you answered yes to any of these questions, then you might be interested in GitHub Cards API, a project that I have been working on. GitHub Cards API is a web service that allows you to generate cards with random quotes and jokes using a simple URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;GitHub Cards API is based on the idea of GitHub Readme Stats, a popular project that lets you create dynamic and customizable stats cards for your GitHub profile. However, GitHub Cards API is different from stats and offers a variety of card types, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Multiple Quotes Card: Cards that shows a random quote from a famous person or a movie, or some motivational quotes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Joke Card: A card that shows a random joke from various categories, such as programming, puns, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And lots more...&lt;/p&gt;

&lt;p&gt;You can also customize the appearance of the cards, such as the card color, font color, background color, shadow, shadow color, etc.&lt;/p&gt;

&lt;p&gt;You can add your own card or theme by contributing in this project which is also registered in the #hacktoberfest2023. This project supports various options for creating your card including card generation from HTML &amp;amp; CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Card
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub-cards.onrender.com%2Fjokes-card%3Ftheme%3Ddark" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub-cards.onrender.com%2Fjokes-card%3Ftheme%3Ddark" alt="Card" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use
&lt;/h3&gt;

&lt;p&gt;Visit endpoint url for all available cards and available options for each card &lt;br&gt;&lt;br&gt;
Endpoint URL: &lt;code&gt;https://github-cards.onrender.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Embed one of these in your README:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Markdown --&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://github-cards.onrender.com/any_card_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;h3&gt;OR&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://github-cards.onrender.com/any_card_name"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Card"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  List of card names currently available
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Available Cards&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Preview&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jokes-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/jokes-card?theme=dark)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/jokes-card?theme=dark" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/jokes-card?theme=dark&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;programming-quotes-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/programming-quotes-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/programming-quotes-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/programming-quotes-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;motivational-quotes-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/motivational-quotes-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/motivational-quotes-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/motivational-quotes-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;word-of-the-day-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/word-of-the-day-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/word-of-the-day-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/word-of-the-day-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;challenge-of-the-week-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/challenge-of-the-week-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/challenge-of-the-week-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/challenge-of-the-week-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;team-work-quote-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/team-work-quote-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github-cards.onrender.com/team-work-quote-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/team-work-quote-card&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bhagavad-geeta-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/bhagavad-geeta-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/bhagavad-geeta-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/bhagavad-geeta-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;random-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/random-card)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/random-card" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/random-card&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;programming-facts-card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;![Card](https://github-cards.onrender.com/programming-facts-card?theme=dark)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github-cards.onrender.com/programming-facts-card?theme=dark" rel="noopener noreferrer"&gt;https://github-cards.onrender.com/programming-facts-card?theme=dark&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  How to contribute
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Add new card
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Fork this repository.&lt;/li&gt;
&lt;li&gt;Add your card in &lt;code&gt;src/cards&lt;/code&gt; directory, you can take the refrence from already added cards.&lt;/li&gt;
&lt;li&gt;Add any data file inside data directory that your card will use. (Languages Support: Hindi &amp;amp; English)&lt;/li&gt;
&lt;li&gt;Add route of your card in &lt;code&gt;index.js&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Add your card api refrence inside in &lt;code&gt;src/help.js&lt;/code&gt; file and also in README.md file.&lt;/li&gt;
&lt;li&gt;Create pull request.&lt;/li&gt;
&lt;li&gt;Note: Data file must have arounf 100 entries minimum.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Add new theme
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Fork this repository.&lt;/li&gt;
&lt;li&gt;If you want to add gradient background then add your gradient code in &lt;code&gt;src/gradients.js&lt;/code&gt; file.
&amp;gt; Take refrence from already added gradients.&lt;/li&gt;
&lt;li&gt;Add your theme name in the &lt;code&gt;src/themes.js&lt;/code&gt; file.
&amp;gt; Theme name should be unique and should be in the second last position of the array.&lt;/li&gt;
&lt;li&gt;Create your theme in &lt;code&gt;src/themes.js&lt;/code&gt; file.
&amp;gt; Take refrence from already added themes.&lt;/li&gt;
&lt;li&gt;Add your theme api refrence inside in &lt;code&gt;src/help.js&lt;/code&gt; file and also in &lt;code&gt;README.md&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/akanshSirohi" rel="noopener noreferrer"&gt;
        akanshSirohi
      &lt;/a&gt; / &lt;a href="https://github.com/akanshSirohi/Github-Cards-API" rel="noopener noreferrer"&gt;
        Github-Cards-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GitHub Cards API is a fast, serverless tool to generate customizable GitHub profile cards. Built on Cloudflare Workers, it supports themes, flexible layouts, and styling—perfect for READMEs, portfolios, and more.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌐 Github Cards API &lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;GitHub Cards API&lt;/strong&gt; is a lightweight, serverless utility that allows you to generate beautifully customizable GitHub profile cards. Built using &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;, this project offers fast, globally distributed performance with minimal overhead. It supports a variety of themes, flexible layout options, and custom styling — making it perfect for embedding in your README, portfolio, or anywhere you want.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🔧 Key Features&lt;/h3&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;✨ &lt;strong&gt;Theme Support&lt;/strong&gt; – Multiple built-in themes and a powerful &lt;code&gt;custom&lt;/code&gt; mode for full design control.&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Card Customization&lt;/strong&gt; – Tweak font size, color, alignment, padding, shadows, and more.&lt;/li&gt;
&lt;li&gt;🖼️ &lt;strong&gt;Live Preview GUI&lt;/strong&gt; – Comes with an interactive app to preview and generate your card with ease.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Serverless &amp;amp; Fast&lt;/strong&gt; – Powered by Cloudflare Workers with optional KV-based caching for performance.&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;Open Source &amp;amp; Extensible&lt;/strong&gt; – Contributions are welcome! Easily extend the card options or renderer logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🚀 Why This Project?&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;This…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/akanshSirohi/Github-Cards-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;blockquote&gt;
&lt;p&gt;Note: If any card or link doesn't work, please be patient and try to open the card again. This project is currently hosted on a free-tier account, so glitches might occur sometimes.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>hacktoberfest23</category>
      <category>hacktoberfest</category>
      <category>github</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
