bwip-js

repository·master·Indexed 25 days ago

https://github.com/metafloor/bwip-js

A pure JavaScript translation of the Barcode Writer in Pure PostScript (BWIPP) engine. It supports generating over 100 types of linear and 2D barcodes across browsers, Node.js, and React Native environments. The library provides platform-specific packages (@bwip-js/node, @bwip-js/browser, @bwip-js/react-native, and @bwip-js/generic) and supports rendering to Canvas, SVG, PNG buffers, and PDF documents via pdfkit.

Tokens
7.1K
Snippets
14
Records
30
Agent score
82%

What's inside bwip-js

  1. Understand barcode scaling and dimensions

    master

    Dimensions and DPI

    bwip-js targets a display resolution of 72dpi. It maps 1pt to 1px. If you need to convert width or height (which are in millimeters) to pixels, use the factor 2.835 px/mm.

    Module Width and Scaling

    Barcodes are composed of "modules" (the narrowest bar in linear barcodes, or the grid unit in 2D barcodes). To ensure barcodes remain "in spec," bwip-js uses a constant module size and grows images in "quantums."

    • The scale parameter effectively requests a specific module width: scale=1 maps to a 1px module, scale=2 to a 2px module, etc.
    • When you specify width or height, bwip-js calculates the requested dimension multiplied by the scale, then divides by the number of modules. It uses the floor of that value as the module width. This ensures the barcode is as large as possible without exceeding the requested dimensions or violating module size specifications.
  2. Add scalable barcodes to PDF documents using pdfkit

    master

    For high-quality, scalable barcodes in PDF documents, use the pdfkit library. The project provides examples for adding barcodes as PDF graphics:

    • examples/pdfkit.js: Server-side PDF generation.
    • examples/drawing-pdfkit.js: Browser-compatible version for client-side PDF generation.
  3. Use bwip-js in Electron

    master

    When using Electron, it is recommended to use the @bwip-js/node package instead of the main bwip-js package to avoid potential issues with bundler interactions with package exports. You can use toBuffer to generate a barcode as a buffer and then convert it to a base64 data URI for display in an <img> tag.

    <script>
      var bwipjs = require('@bwip-js/node');
      bwipjs.toBuffer({ bcid:'qrcode', text:'0123456789' }, function (err, png) {
          if (err) {
            document.getElementById('output').textContent = err;
          } else {
            document.getElementById('myimg').src = 'data:image/png;base64,' + png.toString('base64');
          }
        });
    </script>
  4. Implement a Node.js Request Handler

    master

    You can use bwipjs.request(req, res) to create an HTTP server that renders barcodes based on URL query parameters. The handler ignores the URL path and only operates on the query string.

    Example URL structure: http://localhost:3030/?bcid=isbn&text=978-1-56581-231-4+52250&includetext&guardwhitespace

    // Simple HTTP server that renders barcode images using bwip-js.
    const http   = require('http');
    const bwipjs = require('bwip-js');
    
    http.createServer(function(req, res) {
        if (req.url.indexOf('/?bcid=') != 0) {
            res.writeHead(404, { 'Content-Type':'text/plain' });
            res.end('BWIPJS: Unknown request format.', 'utf8');
        } else {
            bwipjs.request(req, res); // Executes asynchronously
        }
    }).listen(3030);
  5. Install bwip-js

    master

    You can install the main cross-platform package or specific platform-optimized packages. If the main package's exports do not work with your build stack, use one of the platform-specific packages. Note that platform-specific packages are ES modules only (except for the @bwip-js/node package, which also supports require()).

    Main package:

    npm install bwip-js

    Platform-specific packages:

    • Node.js: @bwip-js/node (includes toBuffer())
    • Browser: @bwip-js/browser (includes toCanvas())
    • React Native: @bwip-js/react-native (includes toDataURL())
    • Generic: @bwip-js/generic (SVG and custom drawing context only)
  6. Optimize barcode generation performance in Node.js

    master

    Generating barcodes (especially 2D barcodes) is CPU intensive and can take 100ms - 250ms per operation. To prevent blocking the Node.js event loop, you should offload generation to secondary processes or threads.

    Available patterns in the examples include:

    • Single-process: A basic single-threaded server (server.js).
    • Process Clustering: Using a master process to manage one bwip-js process per CPU, with automatic relaunching (cluster.js).
    • Multi-threading: A single-process, multi-threaded server using Node.js worker threads (requires Node.js 10.5 or higher) (threaded.js).
  7. Use the Online Barcode API

    master

    A bwip-js barcode service is available online to serve barcode images on demand. You can embed these URLs in HTML documents or retrieve them from non-JavaScript servers.

    Note: For JavaScript-based servers, it is recommended to use the bwip-js code directly for better performance rather than calling the online API.

  8. Use @bwip-js/react-native

    master

    For React Native, use the specialized @bwip-js/react-native package. It provides a toDataURL() method that returns an object containing height, width, and uri (the data URL), which can be passed directly to the <Image> component.

    Individual encoders can also be imported as named exports for tree-shaking (e.g., gs1_128). When using named encoders, the bcid in the options object is ignored.

    import { useEffect, useState } from 'react';
    import { Image, PixelRatio } from 'react-native';
    import bwipjs, { type DataURL } from '@bwip-js/react-native';
    
    export default function App() {
      const [source, setSource] = useState<DataURL>();
    
      useEffect(() => {
        bwipjs.toDataURL({
          bcid:        'code128',
          text:        '0123456789',
          scale:       PixelRatio.get(),
          height:      10,
          includetext: true,
          textxalign:  'center',
        }).then(setSource);
      }, []);
    
      if (!source) {
        return null;
      }
    
      const { height, width, uri } = source;
    
      return <Image source={{ uri }} width={width} height={height} />;
    }
  9. Use bwip-js with ES6 Modules (Browser)

    master

    For modern bundlers or ESM environments, you can import bwipjs from the main package or the platform-specific @bwip-js/browser package.

    To enable tree-shaking and reduce bundle size, you can import individual encoders as named exports. The exported names match the bcid names, but dashes (-) are replaced with underscores (_). For example, gs1-128 becomes gs1_128.

    import bwipjs from 'bwip-js';           // Main package
    // or
    import bwipjs from '@bwip-js/browser';  // Platform-specific
    
    // Tree-shaking individual encoders:
    import { gs1_128 } from 'bwip-js';
    
    try {
        gs1_128('my-canvas', options);
    } catch (e) {
        // `e` may be a string or Error object
    }
  10. Use bwip-js in the Browser

    master

    To use bwip-js in a browser without a bundler, include the minified script in your HTML <head>:

    <script type="text/javascript" src="url-path-to/bwip-js/dist/bwip-js-min.js"></script>

    This adds a global bwipjs object. You can render barcodes directly to a <canvas> element using bwipjs.toCanvas(). The method automatically resizes the canvas to match the generated barcode image.

    try {
        // The return value is the canvas element
        let canvas = bwipjs.toCanvas('mycanvas', {
            bcid:        'code128',       // Barcode type
            text:        '0123456789',    // Text to encode
            scale:       3,               // 3x scaling factor
            height:      10,              // Bar height, in millimeters
            includetext: true,            // Show human-readable text
            textxalign:  'center',        // Always good to set this,
        });
    } catch (e) {
        // `e` may be a string or Error object
    }
  11. Use the bwip-js CLI to generate barcodes

    master

    The bwip-js command-line interface allows you to generate barcode images (PNG or SVG) directly from your terminal. You can provide the symbol name and text as positional arguments or via flags, followed by any configuration options and the output filename.

    Basic Syntax:

    # Using positional arguments
    bwip-js <symbol-name> <text> [options...] <output-file>.
    
    # Using explicit flags
    bwip-js --bcid=<symbol-name> --text=<text> [options...] <output-file>

    Examples:

    # Generate a Code 128 barcode with red text
    bwip-js code128 012345678 includetext textcolor=ff0000 my-code128.png
    
    # Generate a QR code as an SVG
    bwip-js qrcode 'https://bwip-js.metafloor.com' qrcode.svg
    bwip-js code128 012345678 includetext textcolor=ff0000 my-code128.png
  12. Render barcodes to an <img> tag in the Browser

    master

    If you need to display a barcode using an <img> tag or CSS background-image instead of a <canvas> element, you can render to a detached or hidden canvas and then extract the data URL using HTMLCanvasElement.toDataURL().

    let canvas = document.createElement('canvas');
    try {
        bwipjs.toCanvas(canvas, options);
        document.getElementById('my-img').src = canvas.toDataURL('image/png');
    } catch (e) {
        // `e` may be a string or Error object
    }