Skip to footer content
COMPARE TO OTHER COMPONENTS

Accusoft BarcodeXpress vs IronBarcode: C# Barcode Library Comparison

Accusoft BarcodeXpress vs IronBarcode: Licensing, Throughput, and API Trade-offs

When you evaluate a barcode library by its trial build, you expect to see whether it actually works on your images before committing to a purchase. Accusoft BarcodeXpress does not give you that option. In evaluation mode, decoded barcode values are stamped with the string " UNLICENSED accusoft.com " and generated 2D barcodes carry the same stamp. You can verify that the library finds a barcode, but you cannot verify that it reads the barcode correctly. That is a commit-before-you-verify situation, and it is a meaningful friction point before you have even looked at pricing.

Understanding Accusoft BarcodeXpress

Accusoft has been building document imaging software for enterprise environments for decades. BarcodeXpress is part of a broader product family that includes PrizmDoc, ImageGear, and Accusoft Imaging. Teams already using those products encounter a familiar API surface and can lean on an existing Accusoft account relationship. For standalone barcode use, that context provides less value.

The core SDK is available as a NuGet package for .NET Core. The API is instance-based — you create a BarcodeXpress object, configure the Licensing property, then use child reader and writer objects for actual operations. The dual-key licensing system distinguishes BarcodeXpress from most alternatives.

Key architectural characteristics of BarcodeXpress:

  • Instance-based API: Every operation requires a BarcodeXpress instance; static convenience methods are not part of the design
  • Two-layer licensing: SDK licensing (SetSolutionName + SetSolutionKey) and OEM/runtime licensing (SetOEMLicenseKey) are separate systems requiring separate purchases
  • Evaluation mode stamping: In evaluation mode, decoded values are stamped with " UNLICENSED accusoft.com " (and generated 2D barcodes are stamped with the same string), making pre-purchase accuracy testing impossible
  • Manual format specification: The reader requires explicit BarcodeTypes configuration to enumerate which symbologies to search for; unspecified formats are not detected
  • 40 PPM Standard ceiling: The Standard Edition throttles processing to 40 pages per minute, a limit that most teams encounter after deployment rather than before
  • No native PDF support: PDF files must be pre-rendered to images using a separate library before the reader can process them
  • Minimum five runtime licenses: Even a single-server deployment requires purchasing at least five runtime licenses

The Two-Key System Explained

BarcodeXpress splits licensing into two conceptually separate layers:

// BarcodeXpress: two separate license keys required
using Accusoft.BarcodeXpressSdk;

// Constructor takes the path to the runtime files (e.g. ".").
var barcodeXpress = new BarcodeXpress(".");

// Step 1: SDK license (for development).
// SetSolutionName and SetSolutionKey are methods, not properties.
// SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

// Step 2: OEM/runtime license (for production — minimum 5 purchased).
try
{
    barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString");
}
catch (Exception ex)
{
    // Without a valid OEM license, the SDK runs in stamped evaluation mode.
    Console.WriteLine($"OEM license activation failed: {ex.Message}");
}
// BarcodeXpress: two separate license keys required
using Accusoft.BarcodeXpressSdk;

// Constructor takes the path to the runtime files (e.g. ".").
var barcodeXpress = new BarcodeXpress(".");

// Step 1: SDK license (for development).
// SetSolutionName and SetSolutionKey are methods, not properties.
// SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

// Step 2: OEM/runtime license (for production — minimum 5 purchased).
try
{
    barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString");
}
catch (Exception ex)
{
    // Without a valid OEM license, the SDK runs in stamped evaluation mode.
    Console.WriteLine($"OEM license activation failed: {ex.Message}");
}
Imports Accusoft.BarcodeXpressSdk

' BarcodeXpress: two separate license keys required

' Constructor takes the path to the runtime files (e.g. ".").
Dim barcodeXpress As New BarcodeXpress(".")

' Step 1: SDK license (for development).
' SetSolutionName and SetSolutionKey are methods, not properties.
' SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName")
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)

' Step 2: OEM/runtime license (for production — minimum 5 purchased).
Try
    barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString")
Catch ex As Exception
    ' Without a valid OEM license, the SDK runs in stamped evaluation mode.
    Console.WriteLine($"OEM license activation failed: {ex.Message}")
End Try
$vbLabelText   $csharpLabel

The SetSolutionName/SetSolutionKey pair activates the SDK itself. The SetOEMLicenseKey call activates production deployment capabilities. Both must be present and valid for a production deployment to return barcode values without the " UNLICENSED accusoft.com " stamp.

In code review, this pattern produces a predictable question: "Why do we have two separate license activations?" The answer — that Accusoft treats SDK licensing and deployment licensing as separate products with separate billing — is not always obvious from the API itself. Teams maintaining this code six months after initial setup often need to trace back to documentation to understand which key is which.

Without a valid OEM license, SetOEMLicenseKey throws and the SDK falls back to evaluation mode. Teams typically wrap activation in try/catch so the failure is logged loudly rather than silently producing stamped barcode values in production:

try
{
    barcodeXpress.Licensing.SetOEMLicenseKey(oemKey);
}
catch (Exception ex)
{
    // In evaluation mode, barcode values are stamped with
    // " UNLICENSED accusoft.com " in the output.
    throw new InvalidOperationException(
        "OEM license activation failed — barcode values will be stamped", ex);
}
try
{
    barcodeXpress.Licensing.SetOEMLicenseKey(oemKey);
}
catch (Exception ex)
{
    // In evaluation mode, barcode values are stamped with
    // " UNLICENSED accusoft.com " in the output.
    throw new InvalidOperationException(
        "OEM license activation failed — barcode values will be stamped", ex);
}
Try
    barcodeXpress.Licensing.SetOEMLicenseKey(oemKey)
Catch ex As Exception
    ' In evaluation mode, barcode values are stamped with
    ' " UNLICENSED accusoft.com " in the output.
    Throw New InvalidOperationException("OEM license activation failed — barcode values will be stamped", ex)
End Try
$vbLabelText   $csharpLabel

This guard is the pattern teams add when they realize that evaluation-mode output silently stamps results rather than throwing during decoding.

Understanding IronBarcode

IronBarcode is a standalone .NET barcode library with no external dependencies beyond its NuGet package. It handles both generation and reading through static factory methods, which means there is no instance lifecycle to manage and no constructor calls scattered through application code.

The single-key licensing model means that what you test in trial mode is what runs in production — the only difference is a watermark on generated barcode images during trial. Decoded values are always complete, which means you can benchmark read accuracy on your actual documents before deciding whether to purchase.

Key characteristics of IronBarcode:

  • Static API design: BarcodeReader.Read() and BarcodeWriter.CreateBarcode() are stateless static methods — no instance management required
  • Single license key: One key covers both development and production deployment; there is no separate runtime license layer
  • Full trial values: Trial mode returns complete decoded values; the watermark applies only to generated output images, not to read results
  • Automatic format detection: IronBarcode auto-detects symbology across all supported formats; no BarcodeTypes enumeration is needed
  • Native PDF support: BarcodeReader.Read("document.pdf") processes PDF files directly without a separate rendering step
  • No throughput ceiling: Processing speed is limited only by hardware and network capacity, not by a software-imposed ceiling
  • Thread-safe by design: Stateless static methods can be called concurrently from any number of threads without instance isolation

Feature Comparison

Feature Accusoft BarcodeXpress IronBarcode
License model SDK license + separate runtime license Single perpetual key
Evaluation mode behavior Barcode values stamped with " UNLICENSED accusoft.com " Full values returned, watermark on generated output only
Throughput limit (Standard) 40 pages per minute No throughput limit
PDF support Requires external PDF library for image extraction Native — BarcodeReader.Read("doc.pdf")
API style Instance-based, verbose configuration Static factory methods, fluent API
Thread safety Instance-per-thread required Stateless static methods — naturally thread-safe
Pricing entry point $1,960+ SDK + $2,500+ runtime (min 5) $749 perpetual (Lite, 1 dev)

Detailed Feature Comparison

Feature Accusoft BarcodeXpress IronBarcode
Licensing
License model SDK key + runtime key Single perpetual key
Minimum runtime licenses 5 (even for 1 server) No runtime license concept
Evaluation mode Values stamped with " UNLICENSED accusoft.com " Full values, watermark on output images only
Perpetual license Not standard — contact sales Yes, all tiers
Annual renewal Required for support Optional
Reading
Format auto-detection Manual — must specify barcode types Automatic across all supported formats
PDF reading Requires external PDF library Native
Multi-barcode per image Yes, with BarcodeTypes configuration Yes, with ExpectMultipleBarcodes option
Result properties BarcodeValue, BarcodeType Value, Format, Confidence, PageNumber
Throughput limit 40 PPM (Standard Edition) No limit at any tier
Generation
Code 128 generation Yes, via writer.BarcodeType Yes, via BarcodeWriter.CreateBarcode()
QR code generation Yes Yes, via QRCodeWriter.CreateQrCode()
QR code with logo Manual image overlay required AddBrandLogo("logo.png") built in
Output formats File save PNG, JPG, PDF, binary data, stream
Platform and Deployment
.NET Framework Separate legacy SDK .NET Framework 4.6.2+
.NET Core / .NET 5+ Yes (.NET Core SDK) .NET Core 3.1+, .NET 5/6/7/8/9
Linux/Docker Yes Yes — Windows x64/x86, Linux x64, macOS x64/ARM
Docker license config License file or license server Environment variable
CI/CD integration Both SDK and runtime keys required One secret
Batch Processing
Thread safety Instance-per-thread required Stateless — Parallel.ForEach safe
Parallel batch Requires per-thread instance management Direct Parallel.ForEach support

License Architecture

The difference in licensing complexity between BarcodeXpress and IronBarcode is most visible when writing initialization code that will run in production.

BarcodeXpress Approach

using Accusoft.BarcodeXpressSdk;

public class BarcodeService
{
    private readonly BarcodeXpress _barcodeXpress;

    public BarcodeService()
    {
        _barcodeXpress = new BarcodeXpress(".");

        // Layer 1: SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

        // Layer 2: OEM/runtime license — separate purchase, minimum 5
        try
        {
            _barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(
                "OEM license activation failed — barcode values will be stamped", ex);
        }
    }
}
using Accusoft.BarcodeXpressSdk;

public class BarcodeService
{
    private readonly BarcodeXpress _barcodeXpress;

    public BarcodeService()
    {
        _barcodeXpress = new BarcodeXpress(".");

        // Layer 1: SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

        // Layer 2: OEM/runtime license — separate purchase, minimum 5
        try
        {
            _barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(
                "OEM license activation failed — barcode values will be stamped", ex);
        }
    }
}
Imports Accusoft.BarcodeXpressSdk

Public Class BarcodeService
    Private ReadOnly _barcodeXpress As BarcodeXpress

    Public Sub New()
        _barcodeXpress = New BarcodeXpress(".")

        ' Layer 1: SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)

        ' Layer 2: OEM/runtime license — separate purchase, minimum 5
        Try
            _barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString")
        Catch ex As Exception
            Throw New InvalidOperationException("OEM license activation failed — barcode values will be stamped", ex)
        End Try
    End Sub
End Class
$vbLabelText   $csharpLabel

This constructor exists entirely to manage two separate license activations before any barcode operation can take place. The try/catch around SetOEMLicenseKey is not optional — without it, the service will silently return stamped values in any environment where the OEM key is missing or misconfigured.

IronBarcode Approach

using IronBarCode;

// In Program.cs or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
using IronBarCode;

// In Program.cs or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode

' In Program.vb or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

That is the complete licensing setup. No separate runtime unlock, no solution name, no two-argument UnlockRuntime call. In Docker, this becomes an environment variable read at startup. In a CI/CD pipeline, it is one secret. In a container orchestrator, it is one environment variable injected into the pod.

Reading Barcodes

Barcode reading reveals the difference between the two libraries' configuration philosophies — BarcodeXpress requires explicit format enumeration and a property-based setup API, while IronBarcode auto-detects everything from a single method call.

BarcodeXpress Approach

Reading with BarcodeXpress requires loading the image into a System.Drawing.Bitmap, assigning the symbology set to reader.BarcodeTypes as a System.Array of BarcodeType values, and calling Analyze(bitmap) to retrieve results. The SDK does not read PDFs directly — documented input formats are TIFF, JPEG, PNG, and BMP:

using Accusoft.BarcodeXpressSdk;
using System.Drawing;

public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
    var barcodeXpress = new BarcodeXpress(".");
    barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
    barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
    barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");

    using var bitmap = new Bitmap(imagePath);

    // BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
    // enum). Pass Enum.GetValues to scan for everything, or assign a
    // narrower array to restrict the search space.
    barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.DataMatrixBarcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = barcodeXpress.reader.Analyze(bitmap);
    return results.Select(r => r.BarcodeValue);
}
using Accusoft.BarcodeXpressSdk;
using System.Drawing;

public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
    var barcodeXpress = new BarcodeXpress(".");
    barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
    barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
    barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");

    using var bitmap = new Bitmap(imagePath);

    // BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
    // enum). Pass Enum.GetValues to scan for everything, or assign a
    // narrower array to restrict the search space.
    barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.DataMatrixBarcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = barcodeXpress.reader.Analyze(bitmap);
    return results.Select(r => r.BarcodeValue);
}
Imports Accusoft.BarcodeXpressSdk
Imports System.Drawing

Public Function ReadAllBarcodes(imagePath As String) As IEnumerable(Of String)
    Dim barcodeXpress = New BarcodeXpress(".")
    barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
    barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
    barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString")

    Using bitmap As New Bitmap(imagePath)
        ' BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
        ' enum). Pass Enum.GetValues to scan for everything, or assign a
        ' narrower array to restrict the search space.
        barcodeXpress.Reader.BarcodeTypes = New BarcodeType() {
            BarcodeType.Code128Barcode,
            BarcodeType.DataMatrixBarcode,
            BarcodeType.QRCodeBarcode
        }

        Dim results As Result() = barcodeXpress.Reader.Analyze(bitmap)
        Return results.Select(Function(r) r.BarcodeValue)
    End Using
End Function
$vbLabelText   $csharpLabel

Analyze takes a Bitmap and returns a Result[]. If a document contains a format not present in the BarcodeTypes array, it will not be found. This becomes maintenance overhead when document sources change. PDFs require pre-rendering to images with a separate library before they can be fed into Analyze.

IronBarcode Approach

using IronBarCode;

public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
    var results = BarcodeReader.Read(imagePath);
    return results.Select(r => r.Value);
}
using IronBarCode;

public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
    var results = BarcodeReader.Read(imagePath);
    return results.Select(r => r.Value);
}
Imports IronBarCode

Public Function ReadAllBarcodes(imagePath As String) As IEnumerable(Of String)
    Dim results = BarcodeReader.Read(imagePath)
    Return results.Select(Function(r) r.Value)
End Function
$vbLabelText   $csharpLabel

IronBarcode auto-detects format across all supported symbologies. If the image contains a Code 128, a QR code, and a DataMatrix, all three come back in the results collection without any configuration change. For more control over reading behavior, the BarcodeReaderOptions class exposes speed, thread count, and multi-barcode settings.

Native PDF reading is also available through the same method:

using IronBarCode;

// Native PDF support — no separate library needed
var results = BarcodeReader.Read("invoice-batch.pdf");

foreach (var result in results)
{
    Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}");
}
using IronBarCode;

// Native PDF support — no separate library needed
var results = BarcodeReader.Read("invoice-batch.pdf");

foreach (var result in results)
{
    Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}");
}
Imports IronBarCode

' Native PDF support — no separate library needed
Dim results = BarcodeReader.Read("invoice-batch.pdf")

For Each result In results
    Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}")
Next
$vbLabelText   $csharpLabel

BarcodeXpress does not read PDFs natively. You need to render each page to an image first, using a separate library, then pass those images to the BarcodeXpress reader. That adds a dependency, adds a conversion step, and adds another licensing cost depending on the PDF library chosen.

Batch Processing and Thread Safety

High-volume barcode processing exposes the architectural difference between BarcodeXpress's stateful instance model and IronBarcode's stateless static API.

BarcodeXpress Approach

BarcodeXpress is instance-based and its reader object is stateful. Parallel processing requires one instance per thread, with the full two-layer license initialization repeated in each thread context:

using Accusoft.BarcodeXpressSdk;
using System.Collections.Generic;
using System.Drawing;

public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
    var results = new Dictionary<string, string>();

    foreach (var path in imagePaths)
    {
        using var bitmap = new Bitmap(path);

        _barcodeXpress.reader.BarcodeTypes = new[]
        {
            BarcodeType.Code128Barcode,
            BarcodeType.QRCodeBarcode
        };

        var barcodes = _barcodeXpress.reader.Analyze(bitmap);
        if (barcodes.Length > 0)
            results[path] = barcodes[0].BarcodeValue;
    }

    return results;
}
using Accusoft.BarcodeXpressSdk;
using System.Collections.Generic;
using System.Drawing;

public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
    var results = new Dictionary<string, string>();

    foreach (var path in imagePaths)
    {
        using var bitmap = new Bitmap(path);

        _barcodeXpress.reader.BarcodeTypes = new[]
        {
            BarcodeType.Code128Barcode,
            BarcodeType.QRCodeBarcode
        };

        var barcodes = _barcodeXpress.reader.Analyze(bitmap);
        if (barcodes.Length > 0)
            results[path] = barcodes[0].BarcodeValue;
    }

    return results;
}
Imports Accusoft.BarcodeXpressSdk
Imports System.Collections.Generic
Imports System.Drawing

Public Function ProcessBatch(imagePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
    Dim results As New Dictionary(Of String, String)()

    For Each path In imagePaths
        Using bitmap As New Bitmap(path)
            _barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
                BarcodeType.Code128Barcode,
                BarcodeType.QRCodeBarcode
            }

            Dim barcodes = _barcodeXpress.reader.Analyze(bitmap)
            If barcodes.Length > 0 Then
                results(path) = barcodes(0).BarcodeValue
            End If
        End Using
    Next

    Return results
End Function
$vbLabelText   $csharpLabel

The Standard Edition also enforces a 40-page-per-minute ceiling. A batch of 100,000 documents at 40 PPM takes roughly 41 hours to complete. The Professional Edition removes this cap but at a higher per-developer cost — in addition to the runtime licenses already purchased.

IronBarcode Approach

using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;

// IronBarcode — parallel batch with thread-safe static API
var files = Directory.GetFiles("/incoming/scans", "*.png");
var allResults = new ConcurrentBag<string>();

Parallel.ForEach(files, file =>
{
    var r = BarcodeReader.Read(file);
    foreach (var barcode in r)
        allResults.Add($"{file}: {barcode.Value}");
});
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;

// IronBarcode — parallel batch with thread-safe static API
var files = Directory.GetFiles("/incoming/scans", "*.png");
var allResults = new ConcurrentBag<string>();

Parallel.ForEach(files, file =>
{
    var r = BarcodeReader.Read(file);
    foreach (var barcode in r)
        allResults.Add($"{file}: {barcode.Value}");
});
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

' IronBarcode — parallel batch with thread-safe static API
Dim files = Directory.GetFiles("/incoming/scans", "*.png")
Dim allResults = New ConcurrentBag(Of String)()

Parallel.ForEach(files, Sub(file)
    Dim r = BarcodeReader.Read(file)
    For Each barcode In r
        allResults.Add($"{file}: {barcode.Value}")
    Next
End Sub)
$vbLabelText   $csharpLabel

Because IronBarcode's static methods are stateless, Parallel.ForEach over them is safe with no instance isolation required. IronBarcode imposes no throughput ceiling at any pricing tier. For tuning read performance, the BarcodeReaderOptions class provides ReadingSpeed and MaxParallelThreads settings:

using IronBarCode;

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = true,
    MaxParallelThreads = 4
};

var results = BarcodeReader.Read("warehouse-scan.png", options);
using IronBarCode;

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = true,
    MaxParallelThreads = 4
};

var results = BarcodeReader.Read("warehouse-scan.png", options);
Imports IronBarCode

Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Balanced,
    .ExpectMultipleBarcodes = True,
    .MaxParallelThreads = 4
}

Dim results = BarcodeReader.Read("warehouse-scan.png", options)
$vbLabelText   $csharpLabel

ReadingSpeed.Balanced is the default. Use ReadingSpeed.Faster for high-throughput pipelines where the barcodes are clean, or ReadingSpeed.Detailed for damaged or low-contrast images.

API Mapping Reference

Accusoft BarcodeXpress IronBarcode
new BarcodeXpress(".") Static methods — no instance required
Licensing.SetSolutionName("...") IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Licensing.SetSolutionKey(int, int, int, int) (removed — not needed)
Licensing.SetOEMLicenseKey(string) (removed — no separate runtime license concept)
try/catch around OEM activation (removed — license is always either valid or not)
reader.Analyze(bitmap) (loads System.Drawing.Bitmap first) BarcodeReader.Read(path)
reader.BarcodeTypes = new[] { BarcodeType.Code128Barcode, ... } (removed — auto-detection handles all formats)
result.BarcodeValue result.Value
result.BarcodeType result.Format
writer.BarcodeType = BarcodeType.Code128 BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128)
writer.BarcodeValue = "data" (first argument to CreateBarcode)
writer.SaveToFile(path) .SaveAsPng(path)
40 PPM Standard limit No throughput limit at any tier
Evaluation: values stamped with " UNLICENSED accusoft.com " Trial: full values, watermark on output images only

When Teams Consider Moving from Accusoft BarcodeXpress to IronBarcode

Scaling Beyond the 40 PPM Wall

The Standard Edition limit of 40 pages per minute sounds generous until a business team decides to run end-of-day batch processing on a year's worth of archived invoices. A batch of 100,000 documents at that rate takes roughly 41 hours to complete. Moving to the Professional Edition removes the cap but at a higher per-developer seat cost — on top of runtime licenses already purchased. Teams that discover the throughput ceiling after signing a purchase order often find that the total cost of removing it substantially exceeds initial estimates.

CI/CD Pipeline Licensing Complexity

A typical CI/CD setup runs builds in ephemeral containers. With BarcodeXpress, every build environment needs both the SDK key pair and the runtime unlock keys available, managed as separate secrets. If the runtime key is missing or misconfigured, the build may succeed but integration tests return obscured values — a silent failure mode that is easy to miss in a test pipeline if test assertions are not carefully written against the actual barcode content.

Air-Gapped and Secure Deployment Requirements

Some environments — healthcare systems processing patient records, government document workflows, financial institution back-office processing — cannot have license validation making outbound network calls. BarcodeXpress's runtime license system involves Accusoft's licensing infrastructure, which may be a compliance concern in environments with strict network egress restrictions. Teams operating in those environments often choose libraries whose license validation is entirely local.

Docker and Container Deployment

BarcodeXpress in Docker typically requires either mounting a license file into the container at a known path or configuring a license server and pointing the container at it. Both approaches add deployment complexity — license files need to be distributed and kept in sync, and a license server is an additional piece of infrastructure to maintain. Teams moving to microservice architectures or serverless deployment patterns find that the configuration-file approach does not translate cleanly into immutable container images.

Evaluation Accuracy Requirements

Teams that need to validate read accuracy on their own documents before committing to a purchase find BarcodeXpress's evaluation mode fundamentally limiting. Testing against real-world document scans — checking whether the library handles low-contrast barcodes, skewed images, or multi-barcode pages — requires complete decoded values. Partially obscured output reveals only that the library found a barcode, not whether it read it correctly.

Common Migration Considerations

Instance Management to Static Calls

BarcodeXpress requires a BarcodeXpress instance to be created and licensed before any operation. IronBarcode's static methods need no instance. Teams migrating typically have a BarcodeService class whose constructor is largely licensing boilerplate — after migration, that constructor can be removed entirely or reduced to a single license key assignment.

BarcodeTypes Enumeration Removal

Every BarcodeXpress read operation requires a BarcodeTypes Array assignment to enumerate which symbologies to search for. IronBarcode auto-detects all supported formats by default. During migration, all reader.BarcodeTypes = ... assignments can be deleted without replacement. If there is a performance reason to restrict the search space, BarcodeReaderOptions supports format filtering as an explicit opt-in rather than a required default.

Result Property Name Changes

Two property renames affect all result-processing code: result.BarcodeValue becomes result.Value, and result.BarcodeType becomes result.Format. A solution-wide search-and-replace handles both. IronBarcode results also expose result.Confidence and result.PageNumber, which have no BarcodeXpress equivalent and can be used for additional filtering without code changes to existing result handling.

Docker License Configuration

BarcodeXpress Docker deployments typically use a mounted license configuration file. IronBarcode uses an environment variable. The migration involves removing the COPY instruction for the config file and adding a single environment variable assignment. In Kubernetes, the license key becomes a secret reference in the pod spec rather than a mounted volume.

Additional IronBarcode Capabilities

Beyond the core features covered in this comparison, IronBarcode provides capabilities that are not part of BarcodeXpress's offering:

  • QR Code with Logo: QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png") embeds a brand image in a QR code natively, with configurable error correction level to maintain scan reliability
  • Barcode Stamping on PDFs: Write barcodes directly onto existing PDF documents without a separate PDF library
  • Batch Export: Process entire PDF documents in one call and receive per-page results with page number, format, value, and confidence score

.NET Compatibility and Future Readiness

IronBarcode supports .NET Framework 4.6.2 and later, .NET Core 3.1, and .NET 5, 6, 7, 8, and 9. Platform targets include Windows x64 and x86, Linux x64, and macOS x64 and ARM. BarcodeXpress for .NET Core is a separate SDK from the legacy .NET Framework edition — teams upgrading their application's target framework need to account for this. IronBarcode's single package covers all supported runtimes. Regular updates track new .NET releases as they are published.

Conclusion

BarcodeXpress and IronBarcode represent two different design philosophies for commercial .NET barcode libraries. BarcodeXpress treats SDK access and production deployment as separate licensed products with separate billing, separate key systems, and separate minimum purchase requirements. IronBarcode treats the library as a single product with a single key that covers every environment from development to production.

BarcodeXpress is a reasonable choice for teams already embedded in the Accusoft product ecosystem — organizations using PrizmDoc or ImageGear will find BarcodeXpress's API familiar and their Accusoft account relationship useful for consolidated support. For those teams, the two-key licensing system is an established operational pattern rather than new friction. The SDK also suits environments where document sources are well-controlled and format requirements are stable, making the manual BarcodeTypes specification an acceptable one-time configuration rather than ongoing maintenance.

IronBarcode is better suited to teams deploying to containers, CI/CD pipelines, and cloud environments where license management complexity directly affects operational overhead. The auto-detection model, static API, and native PDF support reduce the surface area of integration code, and the single-key licensing model simplifies secrets management across development, test, and production environments. For teams that need to evaluate read accuracy before purchasing, the complete trial output — watermark on generated images, not on read results — allows genuine pre-purchase benchmarking.

The pricing difference is significant at every tier. At the single-developer level, the gap between BarcodeXpress SDK plus minimum runtime licenses and IronBarcode's Lite tier is substantial. For teams where that cost difference is secondary to Accusoft ecosystem integration, BarcodeXpress remains a coherent choice. For teams evaluating barcode libraries on their own merits, the combination of evaluation-mode limitations, two-key licensing, and throughput ceilings makes IronBarcode the more straightforward option.

Please noteAccusoft is a registered trademark of its respective owner. This site is not affiliated with, endorsed by, or sponsored by Accusoft. All product names, logos, and brands are property of their respective owners. Comparisons are for informational purposes only and reflect publicly available information at the time of writing.

Frequently Asked Questions

What is Accusoft BarcodeXpress?

Accusoft BarcodeXpress is a .NET barcode library for generating and reading barcodes in C# applications. It is one of several alternatives developers evaluate when selecting a barcode solution for .NET projects.

What are the main differences between Accusoft BarcodeXpress and IronBarcode?

IronBarcode uses a static, stateless API requiring no instance management, while Accusoft BarcodeXpress typically requires instance creation and configuration before use. IronBarcode also provides native PDF support, automatic format detection, and single-key licensing across all environments.

Is IronBarcode easier to license than Accusoft BarcodeXpress?

IronBarcode uses a single license key covering both development and production deployments. This simplifies CI/CD pipelines and Docker configurations compared to licensing systems that separate SDK keys from runtime keys.

Does IronBarcode support all barcode formats that Accusoft BarcodeXpress supports?

IronBarcode supports over 30 barcode symbologies including QR Code, Code 128, Code 39, DataMatrix, PDF417, Aztec, EAN-13, UPC-A, GS1, and many more. Format auto-detection means no explicit format enumeration is required.

Does IronBarcode support native PDF barcode reading?

Yes. IronBarcode reads barcodes directly from PDF files using BarcodeReader.Read("document.pdf") without requiring a separate PDF rendering library. Per-page results include page number, barcode format, value, and confidence score.

How does IronBarcode handle batch processing compared to Accusoft BarcodeXpress?

IronBarcode's static methods are stateless and naturally thread-safe, enabling direct use of Parallel.ForEach without per-thread instance management. There is no throughput ceiling at any pricing tier.

What .NET versions does IronBarcode support?

IronBarcode supports .NET Framework 4.6.2+, .NET Core 3.1, and .NET 5, 6, 7, 8, and 9 in a single NuGet package. Platform targets include Windows x64/x86, Linux x64, and macOS x64/ARM.

How do I install IronBarcode in a .NET project?

Install IronBarcode via NuGet: run 'Install-Package IronBarCode' in the Package Manager Console, or 'dotnet add package IronBarCode' in the CLI. No additional SDK installers or runtime files are required.

Can I evaluate IronBarcode before purchasing, unlike Accusoft BarcodeXpress?

Yes. IronBarcode's trial mode returns complete decoded barcode values — only generated output images receive a watermark. You can benchmark read accuracy on your own documents before committing to a purchase.

What is the pricing difference between Accusoft BarcodeXpress and IronBarcode?

IronBarcode starts at $749 for a perpetual single-developer license covering development and production. Pricing details and volume options are available on the IronBarcode licensing page. There is no separate runtime license requirement.

Is it straightforward to migrate from Accusoft BarcodeXpress to IronBarcode?

Migration from Accusoft BarcodeXpress to IronBarcode primarily involves replacing instance-based API calls with IronBarcode's static methods, removing licensing boilerplate, and updating result property names. Most migrations involve reducing code rather than adding it.

Does IronBarcode generate QR codes with logos?

Yes. QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png") embeds a brand image in a QR code natively with configurable error correction. Colored QR codes are also supported via ChangeBarCodeColor().

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me