Barcode scanning for Blazor,
decoded in C#.
QR Code, Data Matrix, Code 128, Code 39, EAN-13, EAN-8, UPC-A, UPC-E and ITF - from the camera or from still images. No barcode SDK and no JavaScript scanner library: the browser opens the camera and copies pixels, and everything after that is managed code you can step into.
dotnet add package Bit.BbScanner
<BbScanner Formats="BbBarcodeFormat.QrCode | BbBarcodeFormat.Ean13" Region="BbScanRegion.CenteredSquare(0.7)" OnScan="HandleScan" /> private void HandleScan(BbBarcodeResult result) => Console.WriteLine($"{result.Format}: {result.Text}");
Live · in this tab
The same decoder a camera frame goes through, on the symbol beside this text.
[JSImport] memory view, no JSON or base64BbBarcodeDecoder needs no browserCapabilities
A scanner component, and the decoder behind it
<BbScanner> owns the camera, the frame loop, the overlays and the controls;
BbBarcodeDecoder turns pixels into a strongly typed BbBarcodeResult - with
the corner points, the raw bytes and the symbol's metadata - wherever .NET runs.
Every parameter, live
Formats, frame rate, processing size, region, duplicate suppression and the advanced
BbScannerOptions - all applied to the running camera without dropping it.
Camera, torch and zoom
Device selection, front and rear cameras, torch and zoom where the hardware offers them - and never a control the hardware will refuse.
Camera control →Aim with a region
A normalized BbScanRegion crops the frame before any pixel is touched, so every
later stage gets cheaper in proportion to the area removed.
Photos and buffers
A built-in file picker for still images, and DecodeImage for pixels the
application already has - tuned for one exhaustive attempt rather than fifteen a second.
Measured, not guessed
Per-stage timings for every frame, and a decoder benchmark that runs in your browser on your device - with no garbage allocated per frame.
Performance →Yours to restyle
Every colour, radius and dimension is a CSS custom property, and the reticle and the messages are render fragments - with right-to-left, reduced motion and forced colours built in.
Customisation →In practice
See it in code
One package, one namespace
No services to register, no script tag and no stylesheet link: the package's initializer
adds the stylesheet and the component imports its own module. Put it on a page rendered
with InteractiveWebAssembly.
dotnet add package Bit.BbScanner @* _Imports.razor *@ @using Bit.BbScanner @* Scan.razor *@ <BbScanner OnScan="r => _last = r" />
Ask for less, get it faster
Narrow Formats to the symbologies you need - an unused one costs nothing because
its decoder is never created - and aim the decoder at the part of the frame that matters.
<BbScanner Formats="BbBarcodeFormat.Ean13" Region="BbScanRegion.CenteredSquare(0.6)" OnScan="AddToBasket" />
Decode without a camera
The pipeline has no dependency on Blazor, JavaScript or a camera: a server decoding uploads, a MAUI app feeding the platform camera's frames, or a unit test uses the same decoder.
API reference →using var decoder = new BbBarcodeDecoder(BbScannerOptions.ForStillImages()); var result = decoder.Decode(rgbaPixels, width, height, BbPixelFormat.Rgba32); if (result is not null) Console.WriteLine($"{result.Format}: {result.Text}"); // result.Corners, result.RawBytes, result.Metadata …
Comparison
Why not wrap a JavaScript scanner?
Wrapping a JavaScript barcode library puts the part that matters - the decoding - on the far side of interop, in code your .NET tests, debugger and server cannot reach. BbScanner keeps only the camera in the browser.
| Concern | JavaScript scanner behind interop | BbScanner |
|---|---|---|
| Where the decoding runs | JavaScript, outside the .NET debugger | C#, in managed code you can step into |
| What crosses interop | Results marshalled back as JSON | One memory-view copy of each frame into a reused buffer |
| Dependencies | A script library to ship and keep up to date | None beyond Microsoft.AspNetCore.Components.Web |
| The result | Whatever shape the library returns | BbBarcodeResult: text, raw bytes, corners, metadata |
| Without a browser | A second decoder for the server | The same BbBarcodeDecoder, anywhere .NET runs |
Where to start
Choose your path
New to BbScanner?
Install, add the namespace, drop the component on a page - scanning in five minutes.
Getting started →No barcode to hand?
Every symbology is drawn on the samples page: open it on a second screen and scan it with the playground.
Sample barcodes →Building with an AI agent?
This site is an MCP server: point your agent at /mcp and it reads the shipped library instead of guessing.
Questions
Frequently asked
Which render modes can open the camera?
WebAssembly: a standalone Blazor WebAssembly app, or the InteractiveWebAssembly pages of
a Blazor Web App, on .NET 8, 9 and 10. Under Blazor Server and Blazor Hybrid the component reports
NotSupported instead, and BbBarcodeDecoder decodes pixels in-process there.
Why does the camera not start on my test server?
Browsers only expose the camera in a secure context - a page served over HTTPS, or from
localhost. Anywhere else the component reports NotSupported straight away,
with a message that says so, rather than waiting on a prompt that will never appear.
How does it avoid misreads?
Misreading is treated as worse than missing: check digits and guard patterns are verified, a Reed-Solomon correction is only accepted when the corrected block re-verifies, and ITF, UPC-E and unchecked Code 39 results must repeat on a second scan line before they are reported.
Does it read PDF417?
PDF417 is implemented end to end except its symbol character table, which is specification data the library cannot derive. It ships a placeholder table, does not create the PDF417 reader while that is the case, and reads real symbols once the specification table is registered.
Point it at a barcode
One package, one namespace, one component - and the camera hands its pixels to C#.
dotnet add package Bit.BbScanner