View on GitHub

bwip-js // Barcode Writer in Pure JavaScript

Download this project as a .zip file Download this project as a tar.gz file

bwip-js bwip-js is a translation to native JavaScript of the amazing code provided in Barcode Writer in Pure PostScript. The translated code can run on any modern browser or JavaScript-based server framework.

The library has encoding modules for over 100 different barcode types and standards. All linear and two-dimensional barcodes in common use (and many uncommon ones) are available. An exhaustive list of supported barcode types can be found at the end of this document. Barcodes are generated as PNG images (node-js and react-native) or to a canvas (browser) or as SVG (all platforms).

As of version 4.5, bwip-js has been partitioned into four platform-specific packages plus the cross-platform main package. The sub-packages are currently experimental but are the solution to current build chains not properly supporting the exports map in package.json. Please use them and report any issues you find.

Status

Supported Platforms

Installation

The bwip-js package has been partitioned into four platform-specific packages plus the main cross-platform package. If you install the main package and cannot get its exports to work with your build stack, try installing a platform-specific package. The platform-specific packages are ES modules only, so you will need a modern build environment. The exception is the node package, which also contains a require() compatible export.

You can download the main package using:

npm install bwip-js

Or one of the platform-specific packages using:

npm install @bwip-js/node
npm install @bwip-js/browser
npm install @bwip-js/react-native
npm install @bwip-js/generic

The node, browser and react-native packages include both an image rending interface (toCanvas() on the browser, toBuffer() on node, toDataURL() on react-native), plus the SVG and custom drawing context interfaces.

The generic package contains only exports that run on any platform, namely the SVG and custom drawing context interfaces.

The latest code can be obtained from github:

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

The bwip-js branches and the npm versions are automatically sync'd with each release. The main package is located under the master branch; the platform-specific packages are maintained under their like-named branches.

Online Barcode Generator

An online barcode generator demonstrates all of the features of bwip-js. The app is also available in the root bwip-js directory. See Demo HTML App.

Online Barcode API

A bwip-js barcode service is available online, ready to serve up barcode images on demand.

You can generate barcodes from anywhere on the web. Embed the URLs in your HTML documents or retrieve the barcode images directly from your non-JavaScript server. (JavaScript-based servers should use the bwip-js code directly - it will be a lot more performant.)

For details on how to use this service, see Online Barcode API.

Working With bwip-js Methods

Most of the public methods of the bwip-js export use an options object. Only two values are required:

All remaining options are optional, though you may find some quite useful.

The options values can be divided into two parts, bwip-js specific options and BWIPP options.

The bwip-js options are:

For the BWIPP specific options, you will need to consult the BWIPP documentation to determine what options are available for each barcode type.

All of the BWIPP color options (e.g. barcolor, textcolor, bordercolor) can be specified using either RGB, RRGGBB or CCMMYYKK formats or the CSS-style #RGB and #RRGGBB formats.

Note that bwip-js normalizes the BWIPP width and height options to be in millimeters. The resulting images are rendered at 72 dpi. To convert to pixels, use a factor of 2.835 px/mm (72 dpi / 25.4 mm/in). The bwip-js scale options multiply the width, height, and padding.

An important note about the BWIPP width and height parameters.

Barcodes have the concept of module width (and height if a two-dimensional barcode). For linear barcodes, the module width is the width of the narrowest bar, and all other bar widths are a multiple of it. For 2D symbols, module width and height are the dimensions of the square or rectangle that defines the symbol's layout grid.

For a barcode to be "in spec", the individual module dimensions must be consistent throughout the symbol. With high resolution printing, you can add/subtract a dot to adjust the size of individual modules so the overall image meets the requested width or height, while still keeping the module size within spec. This is the intention behind BWIPP's width and height parameters.

bwip-js is designed for web usage, with a target display resolution of 72dpi. (All of BWIPP's internals are calculated in points and bwip-js just maps 1pt to 1px.) At that low resolution, it is not possible to add or subtract pixels without causing the symbol to go out of spec. Imagine a fairly common module width of 2px. If you add or subtract a pixel, you have changed the size by 50%. Typical barcode specs require module sizes to be within 5-10 pecent of nominal.

For this reason, bwip-js uses a constant module size so the resulting image is as large as possible, without exceeding the requested width or height. The design causes the rendered barcodes to grow in "quantums". An image will be X-pixels wide with a module with of 2px, and Y-pixels wide with a module width of 3px, and can not vary between those two sizes.

With bwip-js, the scale parameters can be thought of as requesting a particular module width. scale=1 maps to a 1px module. scale=2 is a 2px module. Etc.

When you specify width, you are effectively changing the scale of the final image. Internally, bwip-js calcuates the requested width x scale, then divides by the number of modules the symbol requires. The floor of that value is the module width (scale) of the rendered barcode.

Browser Usage

To use in a browser without a bundler, add the following to the head of your page:

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

While developing your project, you may want to use dist/bwip-js.js to get better stack traces.

If you are using RequireJS or a common-js bundling utility, the bwip-js scripts are structured as UMDs and should work with your environment.

The scripts adds a single bwipjs global object. To draw a barcode to a canvas:

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
}

The bwipjs.toCanvas() method takes two parameters:

On return from toCanvas(), the barcode image will be fully rendered to the canvas.

If you would prefer to display the barcode using an <img> tag or with CSS background-image, pass in a detached or hidden canvas, and use the canvas method HTMLCanvasElement.toDataURL to get a data URL. For example:

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
}

Browser ES6 Module Usage

The ESM provides the same API as the standard browser module using:

import bwipjs from 'bwip-js';           // If using the main package import
  // or
import bwipjs from '@bwip-js/browser';  // Platform-specific package import

// ... identical bwipjs.toCanvas() interface as above ...

The ESM also facilitates bundler tree shaking by providing the individual encoders as named exports. Each exported encoder functions identically to bwipjs.toCanvas().

The exported names are the same as the bcid names, with the caveat that dashes - are replaced with underscores _. For example, to import the gs1-128 encoder, you would use:

import { gs1_128 } from 'bwip-js';
  // or
import { gs1_128 } from '@bwipjs/browser';

try {
    gs1_128('my-canvas', options);
} catch (e) {
    // `e` may be a string or Error object
}

Node.js Request Handler

The online barcode API is implemented as a Node.js application. See the Online Barcode API for details on how the URL query parameters must be structured.

A working, minimal example of how to use the request handler can be found in server.js:

// Simple HTTP server that renders barcode images using bwip-js.
const http   = require('http');
const bwipjs = require('bwip-js');

// This shows how to load the Inconsolata font, supplied with the bwip-js distribution.
// The path to your fonts will be different.
//bwipjs.loadFont('Inconsolata', 100,
//      require('fs').readFileSync('./fonts/Inconsolata.otf', 'binary'));

http.createServer(function(req, res) {
    // If the url does not begin /?bcid= then 404.  Otherwise, we end up
    // returning 400 on requests like favicon.ico.
    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);

If you run the above code on your local machine, you can test with the following URL:

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

The bwip-js request handler only operates on the URL query parameters and ignores all path information. Your application is free to structure the URL path as needed to implement the desired HTTP request routing.

Node.js Image Generator

You can use bwip-js to generate PNG images directly.

const bwipjs = require('bwip-js');

bwipjs.toBuffer({
        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
    }, function (err, png) {
        if (err) {
            // `err` may be a string or Error object
        } else {
            // `png` is a Buffer
            // png.length           : PNG file length
            // png.readUInt32BE(16) : PNG image width
            // png.readUInt32BE(20) : PNG image height
        }
    });

If you would prefer to work with Promises, omit the callback function and toBuffer() will return a Promise:

bwipjs.toBuffer({
        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
    })
    .then(png => {
        // `png` is a Buffer as in the example above
    })
    .catch(err => {
        // `err` may be a string or Error object
    });

Node.js ES6 Module Usage

The ESM provides the same API as require('bwip-js') using:

import bwipjs from 'bwip-js';           // If using the main package import
  // or
import bwipjs from '@bwip-js/node';     // Platform-specific package import

// ... identical to the examples above ...

The ESM also facilitates bundler tree-shaking by providing the individual encoders as named exports. Each exported encoder functions identically to bwipjs.toBuffer().

The exported names are the same as the bcid names, with the caveat that dashes - are replaced with underscores _. For example, to import the gs1-128 encoder, you would use:

import { gs1_128 } from 'bwip-js';
  // or
import { gs1_128 } from '@bwip-js/node';

try {
    let buf = await gs1_128(options);
} catch (e) {
    // `e` may be a string or Error object
}

When named encoders are called, the bcid value in the options object is ignored.

SVG (All Platforms)

The easiest way to generate an SVG barcode image is with the toSVG() method. It takes the same options object as the other rendering methods.

The method is synchronous.

let svg = bwipjs.toSVG({
        bcid:        'code128',       // Barcode type
        text:        '0123456789',    // Text to encode
        height:      12,              // Bar height, in millimeters
        includetext: true,            // Show human-readable text
        textxalign:  'center',        // Always good to set this
        textcolor:   'ff0000',        // Red text
    });

The return value from toSVG() is a string containing a fully qualified SVG definition, including a viewBox attribute that defines the natural width and height of the image, in pixels.

<svg viewBox="0 0 242 200" xmlns="http://www.w3.org/2000/svg">
   ...
</svg>

The viewBox will always have origin 0 0.

To display in an HTML page, the following should provide a good start:

let [ , width, height ] = /viewBox="0 0 (\d+) (\d+)"/.exec(svg);
let span = document.createElement('span');
span.style.display = 'inline-block';
span.style.width = width + 'px';
span.style.height = height + 'px';
span.innerHTML = svg;
document.body.appendChild(span);

The toSVG() method links to all BWIPP encoders, so it cannot be used with tree-shaking. To reduce bundled size, you can import only the barcode types you need, along with the built-in SVG drawing interface.

import { qrcode, drawingSVG } from 'bwip-js';
  // or <platform> one of : browser, node, react-native, generic
import { qrcode, drawingSVG } from '@bwip-js/<platform>'; 

// drawingSVG() returns a bwip-js drawing object.
let svg = qrcode(options, drawingSVG());

React Usage

The following is a minimal example of bwip-js in a React app. It is based on the default App.js file generated by create-react-app.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import bwipjs from 'bwip-js';           // If using the main package import
  // or
import bwipjs from '@bwip-js/browser';  // Plaform-specific package import

class App extends Component {
  componentDidMount() {
    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
    }
  }
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <canvas id="mycanvas"></canvas>
      </div>
    );
  }
}
export default App;

See the Browser Usage section for details on the toCanvas() method.

See the ES6 Browser Module Usage section for details on importing encoders directly.

React Native

React-native has considerable legacy build environments that are not compatible with the modern exports map in package.json. For this reason, it is recommended to install the react-native package @bwip-js/react-native.

The react-native module provides a specialized version of the toBuffer() method, called toDataURL(). The return value is an object with the following properties:

The returned object is designed to be used with the <Image> component:

import React from 'react';
import bwipjs from '@bwip-js/react-native';

const BarCode = (options) => {
    let img = null;
    try {
        img = await bwipjs.toDataURL(options);
    } catch (e) {
        // `e` may be a string or Error object
    }
    return (
        <Image
            style={{ height:img.height, width:img.width }}
            source={{ uri:img.uri }}
        />
    );
};

The bwip-js exports also facilitate bundler tree-shaking by providing the individual encoders as named exports. Each exported encoder functions identically to bwipjs.toDataURL().

The exported names are the same as the bcid names, with the caveat that dashes - are replaced with underscores _. For example, to import the gs1-128 encoder, you would use:

import { gs1_128 } from '@bwip-js/react-native';

try {
    let buf = await gs1_128(options);
} catch (e) {
    // `e` may be a string or Error object
}

When named encoders are called, the bcid value in the options object is ignored.

Electron Example

With electron, you have the choice to use either the node-specific or browser-specific package. It is not recommended to use the main bwip-js package as developers have reported issues with how the bundler interacts with the package exports.

This is an example index.html file for a basic, single window app, using the node-js package:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    Node.js <script>document.write(process.versions.node)</script>,
    Chromium <script>document.write(process.versions.chrome)</script>,
    Electron <script>document.write(process.versions.electron)</script>,
    bwip-js <script>document.write(bwipjs.BWIPJS_VERSION)</script>,
    and BWIPP <script>document.write(bwipjs.BWIPP_VERSION)</script>.
    <br><br><img id="myimg">
    <pre id="output"></pre>
  </body>

  <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>
</html>

Command Line Interface

bwip-js can be used as a command line tool when installed globally:

$ npm install -g bwip-js
$ bwip-js
Usage: bwip-js symbol-name text [options...] file-name
       bwip-js --bcid=symbol-name --text=text [options...] file-name

Example:
       bwip-js code128 012345678 includetext textcolor=ff0000 my-code128.png

file-name must be type: .png or .svg

Try 'bwip-js --help' for more information.
Try 'bwip-js --symbols' for a list of supported barcode symbols.

To use a custom font with the command line utility, use the --loadfont option. It takes one of three formats:

--loadfont=font-name,y-mult,x-mult,path-to-font-file
--loadfont=font-name,size-mult,path-to-font-file
--loadfont=font-name,path-to-font-file

For example:

$ bwip-js code128 12345678 includetext textfont=CONS textxalign=center \
  loadfont=CONS,250,100,../fonts/Inconsolata.otf /tmp/code128.png

The above demonstrates how to maniplulate the font metrics so the characters appear tall and narrow.

Demo HTML App

demo.html located in the root bwip-js directory is a full featured demonstation of bwip-js barcode rendering. It uses bwip-js' built-in graphics to draw to a canvas. The images produced will match pixel-for-pixel with the images produced by the same nodejs usage.

Examples

There are example html and node apps provided with the project including how to write your own drawing interface, generating SVG barcode images, and adding scalable barcodes to a pdfkit document.

See the examples README for more details.

Supported Barcode Types