There are many use cases requiring to generate barcodes and QR codes in Angular applications on the fly.

In the Angular ecosystem, there are several libraries that can help you generate barcodes and QR codes. They are frequently based on popular libraries like ZXing. or JsBarcode.

One of the most promising libraries for generating barcodes and QR codes in Angular is zxing-wasm.

It is a C++ implementation of the ZXing barcode library compiled to WebAssembly (WASM). It is fast and efficient and can be used in both the browser and Node.js.

In this article, we will show how to use zxing-wasm to render barcodes and QR codes in an Angular demo application.

We are using Angular v19 in this article to benefit from the elegance of the new resource API. However, the code should work with some adaptions also with older Angular versions as well.

BarcodeService: Generating the barcodes and QR codes

BarcodeService is a service that generates barcodes and QR codes. It uses the writeBarcodeToImageFile from zxing-wasm/writer.

writeBarcodeToImageFile has two parameters:

  • the text to be encoded
  • some options for the writer, the most important is the format which can be one of "Aztec", "Codabar", "Code128", "Code39", "Code93", "DataMatrix", "EAN-13", "EAN-8", "ITF", "PDF417", "QRCode", "UPC-A", "UPC-E". We only use the format in this example.

Please note that the writeBarcodeToImageFile function returns a promise that resolves to an object with the following properties:

  • error is an error message if an error occurred
  • image is a Blob object with the image data

The BarcodeService has a method getBarcodeImage that takes the text and the writer options as parameters and returns a promise that resolves to a SafeUrl or null.

The source code is depicted below.

import { inject, Injectable } from '@angular/core';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { writeBarcodeToImageFile, WriterOptions } from "zxing-wasm/writer";

/**
 * Service to generate barcode images using ZXing WASM
 */
@Injectable({
  providedIn: 'root'
})
export class BarcodeService {
  /**
   * DI
   */
  private readonly sanitizer = inject(DomSanitizer);

  /**
   * Method to get barcode image as DataURL
   * @param text is the text to encode
   * @param writerOptions are the options for the writer
   * @returns a promise that resolves to a DataURL as SafeUrl or null
   */
  async getBarcodeImage(text: string, writerOptions?: WriterOptions): Promise<SafeUrl | null> {
    if (!text || text.length === 0) {
      return null;
    }
    const writeResult = await writeBarcodeToImageFile(text, writerOptions);
    if (writeResult.error) {
      console.error('BarcodeService, getBarcodeImage, error:', writeResult.error);
      return null;
    } else if (!writeResult.image) {
      console.error('BarcodeService, getBarcodeImage, no image');
      return null;
    } else {
      return this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(writeResult.image));
    }
  }
}

BarcodeComponent: Rendering barcodes and QR codes to the DOM

BarcodeComponent is a component that renders barcodes and QR codes to the DOM. It uses the BarcodeService to generate the barcode images.

The BarcodeComponent has two required input signals:

  • text is the text to encode as a string.
  • format is the format of the barcode. It can be one of "Aztec", "Codabar", "Code128", "Code39", "Code93", "DataMatrix", "EAN-13", "EAN-8", "ITF", "PDF417", "QRCode", "UPC-A", "UPC-E".

The BarcodeComponent has a resource signal image that loads the barcode image using the BarcodeService.

The source code is depicted below.

import { ChangeDetectionStrategy, Component, inject, input, resource } from '@angular/core';
import { WriteInputBarcodeFormat } from 'zxing-wasm';
import { BarcodeService } from '../../services/barcode.service';

/**
 * Component to display a barcode image
 */
@Component({
  selector: 'app-barcode',
  templateUrl: './barcode.component.html',
  styleUrl: './barcode.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BarcodeComponent {
  /** DI */
  public barcodeService = inject(BarcodeService);
  /**
   * Required input signal providing the text to encode as string
   */
  text = input.required<string>();
  /**
   * Required input signal providing the format of the barcode
   */
  format = input.required<WriteInputBarcodeFormat>();
  /**
   * Barcode image resource, a DataURL as SafeUrl
   */
  image = resource({
    loader: () => {
      return this.barcodeService.getBarcodeImage(this.text(), { format: this.format() });
    }
  });
}

The template of the BarcodeComponent is simple and depicted below.

<div class="barcode">
<img  [src]="image.value()" alt="barcode" />
</div>
<div class="caption">
    {{ text() }}
</div>
<div class="caption">{{ format() }}</div>

AppComponent: Using the BarcodeComponent

The AppComponent is the root component of the Angular demo application. It uses the BarcodeComponent to render barcodes and QR codes to the DOM.

The standalone component imports the BarcodeComponent and uses it in the HTML template to render barcodes and QR codes for all available formats.

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { BarcodeComponent } from './components/barcode/barcode.component';

@Component({
    selector: 'app-root',
    imports: [BarcodeComponent],
    templateUrl: './app.component.html',
    styleUrl: './app.component.scss',
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
}

The HTML template of the AppComponent below depicts the usage of BarcodeComponent.

It renders barcodes and QR codes for all available formats to the DOM.

<app-barcode text="The quick brown fox jumps over the lazy dog" format="Aztec"/>
<app-barcode text="31117013206375" format="Codabar"/>
<app-barcode text="Angular" format="Code128"/>
<app-barcode text="Material" format="Code39"/>
<app-barcode text="Design" format="Code93"/>
<app-barcode text="Reactive" format="DataMatrix"/>
<app-barcode text="4001513007704" format="EAN-13"/>
<app-barcode text="96385074" format="EAN-8"/>
<app-barcode text="1234567895" format="ITF"/>
<app-barcode text="https://advenage.com" format="QRCode"/>
<app-barcode text="03600029145" format="UPC-A"/>
<app-barcode text="02345673" format="UPC-E"/>
<app-barcode text="4001513007704" format="PDF417"/>

With some simple styling, the result in the browser looks like depicted below.