Custom, Animated QR Codes for the Web

@bitjson/qr-code is a zero-dependency, no-framework, customizable, animate-able, SVG-based <qr-code> HTML element. Drop it on any web page or app view, and customize the colors, add a center icon, and animate in, out, or based on activity.

You can try some example animations in your browser, or check out this video demo:

Designing QR Codes

QR codes are often dominant in the interfaces that incorporate them, so customization and animation can really polish a design:

  • Customize the icon and color scheme to indicate the requested asset type, the protocol being used, or to fit a brand identity.
  • Include a subtle intro animation to match the look and feel of the rest of your user interface.
  • Play an in-place animation to indicate detected activity: If your backend detects a URL hit, start a ripple animation. If the user has started a pairing process, rotate the icon or create a loading animation using the QR modules.
  • Play a pronounced exit animation to celebrate a success state: the user completed the checkout, received a payment, paired a device, etc.

Using <qr-code>

The library enables a single, self-contained Web Component, so it works with any framework or build system, and it can also be easily used in a static HTML document – without any compilation step or development server.

Once you import the script, the element simply works anywhere on the page. Here's an example in pure HTML showing most features:

  <img src="assets/1.2-x-to-y-ratio-icon.svg" slot="icon" />

  document.getElementById('qr1').addEventListener('codeRendered', () => {

The only required attribute is contents – the data that will be shown in the QR code. Colors can be customized using module-color, (the color of each small dot), position-ring-color (the rings around the boxes in the corners), and position-center-color (the color in the center of those boxes).

The mask-x-to-y-ratio allows you to include center icons that aren't square, e.g. a horizontal logo might have a ratio of 1.5 or more. Finally, the center icon is provided as an img using slot=icon.


<qr-code>  exposes an API to the rest of the page: the codeRendered event occurs as the QR code is rendered, and animateQRCode allows for animations to be played using Javascript.

Several animation presets are built-in, but it's also very easy to create your own animation. Here's a simple animation that fades-in each individual QR module at random offsets over 2 seconds:

For greater control, you can use the animation previewer built in to the project: just run npm start after cloning the repo. The previewer allows you to slow down the animation or manually scroll through it, which is very helpful in fine-tuning complex, natural-looking animations.

Ensuring good performance of animations requires some care, but the typical guidelines for CSS/SVG animations on the web apply: stick to animating properties that can be handled by GPUs rather than CPUs, and if you're targeting lower-performance hardware, choose animations where lost frames won't be too noticeable. (E.g. the above animation has a similar visual effect even on very inexpensive or old hardware.)

Low/No Maintenance

This project is a revival of an earlier open source project I built at BitPay in 2018 – I forked my old work, cleaned up a few issues, built a demo, improved the documentation, and released v1.0.0 at @bitjson/qr-code on NPM.

Notably, I did not update any dependencies: The project happily continues to use a 5-year old, alpha version of the Stencil toolchain. This highlights the maintainability difference of Web Components: they are self-contained, and they don't need to be continuously tweaked to keep up with the latest web frameworks.

Web Components are a breath of fresh air in the high-turnover world of web development. As a web standard, they isolate parts of your application from the typical maintenance grind.

The <qr-code> element has already been in production across multiple organizations and shifting web frameworks for almost 5 years without any changes. As hardware and web rendering performance has improved, even more complex animations have become performant enough for real usage, all without maintenance effort.