{"id":1006,"date":"2026-07-02T06:38:41","date_gmt":"2026-07-01T23:38:41","guid":{"rendered":"https:\/\/sumberlaba.com\/index.php\/2026\/07\/02\/how-to-build-a-qr-code-generator-from-scratch-a-complete-step-by-step-guide\/"},"modified":"2026-07-02T06:38:41","modified_gmt":"2026-07-01T23:38:41","slug":"how-to-build-a-qr-code-generator-from-scratch-a-complete-step-by-step-guide","status":"publish","type":"post","link":"https:\/\/sumberlaba.com\/index.php\/2026\/07\/02\/how-to-build-a-qr-code-generator-from-scratch-a-complete-step-by-step-guide\/","title":{"rendered":"How to Build a QR Code Generator from Scratch: A Complete Step-by-Step Guide"},"content":{"rendered":"<h1>How to Build a QR Code Generator from Scratch: A Complete Step-by-Step Guide<\/h1>\n<p>QR codes have become an integral part of modern digital interaction, bridging the physical and virtual worlds with a simple scan. Whether you\u2019ve seen them on restaurant menus, product packaging, or business cards, these two-dimensional barcodes store information in a format that any smartphone camera can decode. Building your own QR code generator is not only a rewarding programming project but also gives you full control over customization, output formats, and integration into larger applications. Instead of relying on third-party APIs that may have usage limits or privacy concerns, a self-built generator allows you to generate unlimited codes offline, embed them in web apps, and even experiment with advanced features like adding logos or changing colors.<\/p>\n<p>In this comprehensive tutorial, we will walk you through every step of creating a QR code generator from scratch. We will start by understanding the underlying technology\u2014how QR codes structure data, what error correction means, and the different version sizes. Then we\u2019ll move into the practical coding phase using Python (with the popular <code>qrcode<\/code> library) and also show you how to build a simple web-based interface with HTML, CSS, and JavaScript for those who prefer a browser-based tool. You\u2019ll learn how to generate codes with custom colors, embed logos, choose error correction levels, and export results as high-quality PNG or SVG files. By the end, you\u2019ll have a fully functional generator that you can deploy on your own website or use as a local utility. The guide is designed for intermediate developers, but even beginners can follow along if they have basic familiarity with Python or JavaScript. Let\u2019s dive in.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/via.placeholder.com\/800x600\/4a90d9\/ffffff?text=how%20to%20build%20a%20QR%20code%20generator\" alt=\"Article illustration\" style=\"display:block;margin:20px auto;max-width:100%;height:auto;border-radius:8px;\" \/><\/p>\n<h2>Step 1: Understand the Anatomy of a QR Code<\/h2>\n<p>Before writing a single line of code, it\u2019s critical to understand what a QR code actually contains. A QR code consists of black modules (squares) arranged on a white background. The pattern includes several functional zones: the finder patterns (the three large squares at the corners) that help scanners locate the code, timing patterns that define the grid, alignment patterns for version 2 and above, and the actual data area. The data is encoded using a Reed\u2013Solomon error correction algorithm, which allows the code to be read even if parts are damaged or obscured. QR codes have 40 versions (sizes), from 21\u00d721 modules up to 177\u00d7177 modules. Each version can store a different amount of data, and the capacity depends on the chosen error correction level.<\/p>\n<p>There are four error correction levels: L (low, recovers 7% of data), M (medium, 15%), Q (quartile, 25%), and H (high, 30%). Higher levels allow you to cover part of the code with a logo or withstand more damage, but they reduce the maximum data capacity. For most use cases, level M or Q provides a good balance. Understanding these basics will help you when you later choose parameters in your generator. The actual encoding process involves several steps: data analysis, bit stream generation, error correction codeword calculation, interleaving, and module placement. Fortunately, libraries handle this complexity for you, but knowing the concepts prevents confusion when you see options like \u201cbox_size\u201d or \u201cborder.\u201d<\/p>\n<h2>Step 2: Set Up Your Development Environment<\/h2>\n<p>For the Python approach, ensure you have Python 3.8 or newer installed. You can download it from python.org. We will use the <code>qrcode<\/code> library (a pure Python QR code generator) along with <code>Pillow<\/code> for image manipulation if you plan to add logos or customize colors. Create a virtual environment to keep dependencies isolated:<\/p>\n<pre><code>python -m venv qr_env\nsource qr_env\/bin\/activate  # On Windows: qr_env\\Scripts\\activate\npip install qrcode[pil]<\/code><\/pre>\n<p>The <code>[pil]<\/code> extra installs Pillow automatically. For JavaScript developers, you don\u2019t need any special setup if you\u2019re building a client-side generator; you can use the browser\u2019s Canvas API or a lightweight library like <code>qrcode-generator<\/code> from npm. If you prefer a Node.js environment, install it globally or locally via npm. We\u2019ll cover both approaches in later steps. For now, make sure you have a code editor (VS Code, PyCharm, or even a simple text editor) and a terminal ready. You\u2019ll also need a QR code scanner app on your phone (many free ones available) to test the generated codes.<\/p>\n<h2>Step 3: Generate Your First QR Code \u2013 Python Edition<\/h2>\n<p>Let\u2019s start with the simplest possible generator. Create a new Python file called <code>qr_basic.py<\/code> and import the <code>qrcode<\/code> library. The core function is <code>qrcode.make()<\/code>, which accepts a string of data (URL, text, etc.) and returns an image object. You can then save it with <code>.save()<\/code>.<\/p>\n<p>Example code:<\/p>\n<pre><code>import qrcode\n\ndata = \"https:\/\/www.example.com\"\nimg = qrcode.make(data)\nimg.save(\"my_qr.png\")\n<\/code><\/pre>\n<p>That\u2019s it\u2014run the script and you\u2019ll have a PNG file named <code>my_qr.png<\/code> in your directory. But this basic version gives you little control. To customize, use the <code>QRCode<\/code> class instead. This class allows you to set version, error correction, box size, and border thickness. Then you can generate an image using <code>make_image()<\/code> with custom fill and background colors.<\/p>\n<p>Example with customization:<\/p>\n<pre><code>import qrcode\nfrom qrcode.image.styledpil import StyledPilImage\nfrom qrcode.image.styles.moduledrawers import SquareModuleDrawer\n\nqr = qrcode.QRCode(\n    version=1,\n    error_correction=qrcode.constants.ERROR_CORRECT_M,\n    box_size=10,\n    border=4,\n)\nqr.add_data(\"https:\/\/www.example.com\")\nqr.make(fit=True)\n\nimg = qr.make_image(fill_color=\"darkblue\", back_color=\"white\")\nimg.save(\"my_custom_qr.png\")\n<\/code><\/pre>\n<p>You can also change the module drawer to use rounded squares, circles, or other patterns by importing styles from <code>qrcode.image.styles<\/code>. The <code>StyledPilImage<\/code> class allows you to pass a custom module drawer. However, for most purposes, the default square modules are fine. Experiment with different <code>version<\/code> values (1 to 40) and <code>error_correction<\/code> constants. Note that <code>fit=True<\/code> will automatically select the smallest version that fits your data.<\/p>\n<h2>Step 4: Add a Logo or Embedded Image<\/h2>\n<p>One of the most popular customizations is placing a logo in the center of the QR code. This requires using error correction level H (30% recovery) so that the logo\u2019s obstruction doesn\u2019t break the code. With the <code>qrcode<\/code> library and Pillow, you can overlay a logo image on top of the generated QR code. You must carefully position the logo so it doesn\u2019t cover the finder patterns or timing patterns. The center area is safe as long as the logo is not too large (generally no more than 20% of the overall area).<\/p>\n<p>Here\u2019s a function that adds a logo:<\/p>\n<pre><code>from PIL import Image\n\ndef add_logo(qr_img, logo_path, logo_size=80):\n    qr_width, qr_height = qr_img.size\n    logo = Image.open(logo_path).convert(\"RGBA\")\n    logo.thumbnail((logo_size, logo_size), Image.LANCZOS)\n    # Calculate center position\n    x_pos = (qr_width - logo.size[0]) \/\/ 2\n    y_pos = (qr_height - logo.size[1]) \/\/ 2\n    qr_img.paste(logo, (x_pos, y_pos), logo)\n    return qr_img\n\n# Usage after generating basic QR with high error correction\nqr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)\nqr.add_data(\"https:\/\/example.com\")\nqr.make()\nimg = qr.make_image().convert(\"RGB\")\nimg_with_logo = add_logo(img, \"logo.png\")\nimg_with_logo.save(\"qr_with_logo.png\")\n<\/code><\/pre>\n<p>Notice we used <code>ERROR_CORRECT_H<\/code>. Also, we convert the QR image to RGB before pasting to avoid alpha mode issues. The logo itself should ideally be a PNG with transparency (alpha channel) for a clean overlay. If your logo has a white background, you can mask it. This approach works perfectly for personal projects and even some commercial uses, but remember that overly complex logos can cause scanning failures\u2014test thoroughly on multiple scanners.<\/p>\n<h2>Step 5: Build a Web-Based QR Code Generator Using HTML, CSS, and JavaScript<\/h2>\n<p>If you want a user-friendly interface that runs entirely in the browser, you can build a web-based generator using the <code>qrcode.js<\/code> library or the browser\u2019s Canvas API. We\u2019ll use <code>qrcode.js<\/code> (a popular lightweight library) because it handles all the heavy lifting. Start by creating an HTML file with a text input for data, a color picker for fill and background, a dropdown for error correction, and a button to generate. The result can be displayed as a Canvas element or an inline SVG.<\/p>\n<p>First, include the library via CDN:<\/p>\n<pre><code>&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/qrcodejs\/1.0.0\/qrcode.min.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<p>Then set up your HTML form:<\/p>\n<pre><code>&lt;input type=\"text\" id=\"data-input\" placeholder=\"Enter text or URL\" value=\"https:\/\/example.com\"&gt;\n&lt;select id=\"error-level\"&gt;\n  &lt;option value=\"L\"&gt;Low (7%)&lt;\/option&gt;\n  &lt;option value=\"M\" selected&gt;Medium (15%)&lt;\/option&gt;\n  &lt;option value=\"Q\"&gt;Quartile (25%)&lt;\/option&gt;\n  &lt;option value=\"H\"&gt;High (30%)&lt;\/option&gt;\n&lt;\/select&gt;\n&lt;input type=\"color\" id=\"fill-color\" value=\"#000000\"&gt;\n&lt;input type=\"color\" id=\"back-color\" value=\"#ffffff\"&gt;\n&lt;button onclick=\"generateQR()\"&gt;Generate QR Code&lt;\/button&gt;\n&lt;div id=\"qrcode\"&gt;&lt;\/div&gt;<\/code><\/pre>\n<p>Now the JavaScript function that creates the QR code with the chosen options:<\/p>\n<pre><code>function generateQR() {\n  const data = document.getElementById('data-input').value;\n  const errorLevel = document.getElementById('error-level').value;\n  const fillColor = document.getElementById('fill-color').value;\n  const backColor = document.getElementById('back-color').value;\n\n  \/\/ Clear previous QR\n  document.getElementById('qrcode').innerHTML = '';\n\n  const qr = new QRCode(document.getElementById('qrcode'), {\n    text: data,\n    width: 256,\n    height: 256,\n    colorDark: fillColor,\n    colorLight: backColor,\n    correctLevel: QRCode.CorrectLevel[errorLevel]\n  });\n}\n<\/code><\/pre>\n<p>This generates an inline Canvas with the QR code. To allow downloading, you can add a button that converts the Canvas to PNG using <code>toDataURL()<\/code>. For more advanced features like adding a logo or supporting SVG export, you might need different libraries (like <code>qrcode-svg<\/code> or custom Canvas drawing). The web-based approach is great for non-technical users and can be easily hosted on any static site. Remember to handle edge cases (empty input, too-long data) with appropriate messages.<\/p>\n<h2>Step 6: Output Formats \u2013 PNG, SVG, and More<\/h2>\n<p>Different use cases require different output formats. PNG is ubiquitous for web and print, but SVG (Scalable Vector Graphics) is superior for scalability and small file size. The Python <code>qrcode<\/code> library natively supports saving to PNG via PIL. To save as SVG, you need either the <code>qrcode-svg<\/code> library or you can generate SVG manually from the module matrix. Fortunately, the <code>qrcode<\/code> package includes an SVG image factory. Use <code>qrcode.image.svg.SvgImage<\/code> to produce clean SVG output.<\/p>\n<p>Example of SVG generation in Python:<\/p>\n<pre><code>import qrcode\nfrom qrcode.image.svg import SvgImage\n\nqr = qrcode.QRCode()\nqr.add_data(\"https:\/\/example.com\")\nimg = qr.make_image(image_factory=SvgImage)\nimg.save(\"my_qr.svg\")\n<\/code><\/pre>\n<p>This produces a compact SVG string. For more control (e.g., custom colors), you can subclass <code>SvgImage<\/code> or use <code>SvgPathImage<\/code> for path-based output. SVG files are perfect for logos, print materials, and responsive design because they scale without pixelation. In the browser, you can generate SVG using the <code>qrcode<\/code> library\u2019s <code>toSVG()<\/code> method if available, or by drawing on a Canvas and exporting to SVG with third-party tools. Another format is EPS, which some professional printers require, but that\u2019s less common.<\/p>\n<p>The following table summarizes the most common output formats and their best use cases:<\/p>\n<table>\n<thead>\n<tr>\n<th>Format<\/th>\n<th>Best For<\/th>\n<th>Scalability<\/th>\n<th>Transparency<\/th>\n<th>File Size<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>PNG<\/td>\n<td>Web, social media, basic printing<\/td>\n<td>Limited (raster)<\/td>\n<td>Yes (alpha channel)<\/td>\n<td>Medium to large<\/td>\n<\/tr>\n<tr>\n<td>SVG<\/td>\n<td>Logos, responsive web, high-res printing<\/td>\n<td>Infinite (vector)<\/td>\n<td>Yes<\/td>\n<td>Very small<\/td>\n<\/tr>\n<tr>\n<td>EPS<\/td>\n<td>Professional print, Adobe Illustrator<\/td>\n<td>Infinite (vector)<\/td>\n<td>Limited<\/td>\n<td>Small<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Step 7: Deploy Your Generator \u2013 Local or Cloud<\/h2>\n<p>Once your generator works locally, you might want to share it with others. For Python, you can create a simple Flask or FastAPI web server that exposes an API endpoint. When a user submits data via a form or a GET request, your server generates the QR code image and returns it as a downloadable file. Dockerize the app for easy deployment on platforms like Heroku, AWS, or DigitalOcean. For the JavaScript version, you can upload the HTML\/CSS\/JS files to any static hosting (Netlify, Vercel, GitHub Pages) and it will work immediately without a backend. This is the easiest route for a simple generator.<\/p>\n<p>If you need to generate QR codes programmatically for batch processing (e.g., generating thousands of codes for event tickets), use Python scripts instead of a web interface. The script can read from a CSV file, generate codes with appropriate unique data (like UUIDs or serial numbers), and save them with meaningful filenames. You can also add logging and error handling. For high-traffic web applications, consider caching generated images or using a CDN to serve them. Always validate user input to prevent injection attacks (sanitize the data string).<\/p>\n<h2>Tips and Best Practices for Building a QR Code Generator<\/h2>\n<h3>1. Always Use the Highest Practical Error Correction<\/h3>\n<p>Even if you don\u2019t plan to overlay a logo, using error correction level H (30%) makes your QR codes more resilient to scanning issues like low light, dirty scanners, or minor damage. The trade-off is reduced data capacity, but for most URLs or short text, even version 1 with level H can hold enough. If you anticipate the code being printed on curved surfaces or placed in challenging environments, never drop below level M. Test your codes on at least three different scanner apps (e.g., Google Lens, QR Code Reader, camera default) to ensure readability.<\/p>\n<h3>2. Maintain Sufficient Quiet Zone (Border)<\/h3>\n<p>QR codes require a white border (quiet zone) around them to be scanned correctly. The standard is at least 4 modules wide. In the <code>qrcode<\/code> library, that\u2019s the <code>border=4<\/code> parameter. Many beginner generators omit this or set it too small, causing scanning failures especially when printed on dark backgrounds. If you design a code that will be placed on a colored surface, make sure the quiet zone is pure white or the lightest color of the surface. Some advanced designs embed the QR code into an image and try to incorporate the quiet zone as part of the artwork\u2014but this risks breaking the standard.<\/p>\n<h3>3. Generate Codes at the Correct Physical Size<\/h3>\n<p>When you generate a QR code, the module size (box_size in Python) determines the physical size of each small square. For typical scanning (from a smartphone at 10-30 cm distance), a module size of at least 0.5 mm is recommended. For example, if your code is 25\u00d725 modules (version 2), and you want it to be 2.5 cm (1 inch) wide, each module is 1 mm \u2013 fine. But if you generate a code using default box_size=10 and then resize in an image editor, you risk blurring. Always set the generation parameters so the final image is at least 2\u20133 cm (1 inch) across for reliable scanning. For large outdoor banners, scale up accordingly.<\/p>\n<h2>Frequently Asked Questions (FAQ)<\/h2>\n<h3>Q1: Can I generate QR codes offline?<\/h3>\n<p>Yes, absolutely. The Python library works completely offline \u2013 it does not call any external API. The JavaScript library also runs entirely in the browser after the initial page load, meaning you can generate codes even without an internet connection once the page is cached. This is a key advantage over many online generators that require you to upload data to their servers. Building your own offline generator gives you privacy and reliability.<\/p>\n<h3>Q2: What is the maximum amount of data a QR code can hold?<\/h3>\n<p>The maximum capacity depends on the version (size) and error correction level. For version 40 (177\u00d7177 modules) with error correction L, a QR code can hold up to 7,089 numeric digits, 4,296 alphanumeric characters, or 2,953 bytes of binary data. With the highest error correction (H), these numbers drop to about 1,857 alphanumeric characters. The following table shows capacities for selected versions at error correction M (the most common middle ground):<\/p>\n<table>\n<thead>\n<tr>\n<th>Version<\/th>\n<th>Modules<\/th>\n<th>Numeric<\/th>\n<th>Alphanumeric<\/th>\n<th>Byte (binary)<\/th>\n<th>Kanji<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>21\u00d721<\/td>\n<td>41<\/td>\n<td>25<\/td>\n<td>17<\/td>\n<td>10<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>37\u00d737<\/td>\n<td>224<\/td>\n<td>137<\/td>\n<td>93<\/td>\n<td>57<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>57\u00d757<\/td>\n<td>652<\/td>\n<td>395<\/td>\n<td>271<\/td>\n<td>164<\/td>\n<\/tr>\n<tr>\n<td>20<\/td>\n<td>97\u00d797<\/td>\n<td>2,080<\/td>\n<td>1,256<\/td>\n<td>864<\/td>\n<td>528<\/td>\n<\/tr>\n<tr>\n<td>40<\/td>\n<td>177\u00d7177<\/td>\n<td>5,592<\/td>\n<td>3,376<\/td>\n<td>2,335<\/td>\n<td>1,424<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Q3: Can I add a logo to a QR code and still have it scan?<\/h3>\n<p>Yes, but you must use the highest error correction level (H) because the logo occupies data area. The logo should be placed in the center of the code, and its size should not exceed approximately 20% of the total QR code area. Always test your logo QR code on multiple devices. Some scanners are more tolerant than others. Additionally, keep the logo simple with high contrast against the background of the code. QR code libraries like <code>qrcode<\/code> in Python can also generate \u201cimage QR codes\u201d that embed an image directly, but that\u2019s more advanced.<\/p>\n<h3>Q4: How do I change the color of a QR code?<\/h3>\n<p>Both Python and JavaScript generators allow you to specify fill and background colors. In Python, use the <code>fill_color<\/code> and <code>back_color<\/code> arguments in <code>make_image()<\/code>. In JavaScript via <code>qrcodejs<\/code>, use the <code>colorDark<\/code> and <code>colorLight<\/code> options. However, be cautious with colors \u2013 the scanner needs a high contrast between modules and background. Dark modules should be very dark (black, dark blue, dark green) and the background should be very light (white, light yellow). Avoid red\/green combinations because many scanners interpret colors as grayscale. Always test colored QR codes.<\/p>\n<h3>Q5: What is the difference between static and dynamic QR codes?<\/h3>\n<p>A static QR code embeds the data directly. Once generated, you cannot change the destination URL or text without generating a new code. A dynamic QR code uses a short URL that redirects to the actual destination, which can be changed later. Static codes are simpler and never expire, while dynamic codes require a server to manage redirections but allow analytics (scan count, location) and the ability to update the link without reprinting. The generator you build here creates static codes; if you need dynamic codes, you would need a backend that stores mappings and serves redirects.<\/p>\n<h2>Conclusion<\/h2>\n<p>Building your own QR code generator is a practical and educational project that gives you deep insight into how these ubiquitous barcodes work. You\u2019ve learned the foundational concepts of QR code structure and error correction, set up a development environment, generated your first codes with Python, added custom logos, and even created a web-based interface. You now know how to output both PNG and SVG formats, and you have a clear picture of deployment options from a simple local script to a full web service. The skills you\u2019ve picked up\u2014image manipulation with Pillow, client-side JavaScript libraries, and understanding data encoding\u2014are transferable to many other projects. As next steps, consider extending your generator with features like batch processing from a spreadsheet, creating animated QR codes (by cycling frames), or integrating with a URL shortener for dynamic codes. Remember to always test your creations thoroughly because a QR code that doesn\u2019t scan is useless. Now go ahead, generate your first code, and share it with the world. Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to Build a QR Code Generator from Scratch: A Complete Step-by-Step Guide QR codes have become an integral part of modern digital interaction, bridging the physical and virtual worlds with a simple scan. Whether you\u2019ve seen them on restaurant menus, product packaging, or business cards, these two-dimensional barcodes store information in a format that &hellip; <\/p>\n","protected":false},"author":2716,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[],"tags":[],"class_list":["post-1006","post","type-post","status-publish","format-standard","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts\/1006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/users\/2716"}],"replies":[{"embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/comments?post=1006"}],"version-history":[{"count":0,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts\/1006\/revisions"}],"wp:attachment":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/media?parent=1006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/categories?post=1006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/tags?post=1006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}