blog-teaser

Building a Barcode Scanner App with NativeScript and the barKoder SDK

This guide walks through barkoder_app_nativeScript, a NativeScript demo app built with the official barkoder-nativescript plugin.The goal was to build more than a basic scan screen. This app shows how to structure a practical NativeScript barcode app with:

  • live camera scanning
  • gallery image scanning
  • multiple scan presets
  • runtime scanner controls
  • persistent per-mode settings
  • scan history with saved thumbnails
  • details and review screens

This project mirrors the same Barkoder demo flow used in the other framework ports, but the integration is fully NativeScript-specific.

Why NativeScript + barKoder

NativeScript is a strong fit when you want native mobile UI and native plugin access while staying in TypeScript.

In this app, NativeScript gives us:

  • a native Barkoder camera view in XML layouts
  • direct access to device features such as image picking and sharing
  • native file storage for history and saved scan image

The barKoder SDK provides the scanning engine and specialized barcode features, including:

  • 1D and 2D decoding
  • MultiScan
  • VIN scanning
  • DPM scanning
  • DotCode mode
  • MRZ mode
  • AR mode

What the app includes

The app is organized into the same major screens as the other Barkoder demo apps:

  • Home
  • Scanner
  • Details
  • History
  • About

From the home screen, users can launch:

  • 1D
  • 2D
  • Continuous
  • MultiScan
  • VIN
  • DPM
  • DeBlur
  • DotCode
  • AR Mode
  • MRZ
  • Gallery Scan

Project setup

Install dependencies first: npm install

Then add your license key to .env:

BARKODER_LICENSE_KEY=YOUR_BARKODER_LICENSE_KEY

The app reads this value in app/config.ts:

export const BARKODER_LICENSE_KEY = process.env.BARKODER_LICENSE_KEY ?? '';

For Android builds: npm run build:android For iOS builds: npm run build:ios There is also a TypeScript validation command: npm run typecheck

The NativeScript app id is defined in nativescript.config.ts: id: 'com.barkoderapp.nativescript'

Your Barkoder license should match the app id used for the build.

The plugin stack

This project uses a small set of NativeScript packages:

  • barkoder-nativescript
  • @nativescript/imagepicker
  • @nativescript/social-share
  • @nativescript/core`

barkoder-nativescript powers scanning, @nativescript/imagepicker is used for gallery barcode scanning, and @nativescript/social-share is used for sharing CSV scan output.

1000000087
1000000087

A custom licensed Barkoder view

One NativeScript-specific detail is the custom component in app/components/licensed-barkoder-view.ts.

Instead of setting the license key separately in every screen, the app subclasses the Barkoder view and injects the key in the constructor:

export class LicensedBarkoderView extends (BaseBarkoderView as typeof View) {
  constructor() {
    super();
    (this as any).setLicenseKey(BARKODER_LICENSE_KEY);
  }
}

That component is then used directly in XML:

<Barkoder:LicensedBarkoderView id="barkoderView" class="scanner-view" />

This keeps license setup centralized and makes the scanner screens cleaner.

App architecture

The project is split into a few clear areas:

  • app/home for the launch screen and gallery scan entry
  • app/scanner for live scanning UI and scan lifecycle
  • app/details for single-result review
  • app/history for stored scans
  • app/about for device and version info
  • app/services for history and settings persistence
  • app/utils for scanner defaults and platform helpers
  • app/vendor for Barkoder imports

The main scanner logic is concentrated in app/scanner/scanner-page.ts, while NativeScript XML files define the actual screen layouts.

How live scanner startup works

The live scanner screen uses LicensedBarkoderView directly in app/scanner/scanner-page.xml.

When the page opens, scanner-page.ts:

  1. reads the selected mode from navigation context
  2. loads saved settings for that mode
  3. applies Barkoder configuration
  4. starts scanning

That startup is intentionally delayed slightly so the page is fully ready before scanner configuration kicks in:

setTimeout(() => {
  applyScannerConfiguration();
  startScanning();
}, 250);

The actual scan session uses Barkoder's callback-based API:

barkoderView.startScanning({
  async scanningFinished(results, thumbnails, resultImage) {
    ...
  },
});
image
image

Mode-based scanner behavior

Modes are defined in app/constants.ts, and each mode gets default enabled barcode types and scanner settings in app/utils/scanner-config.ts.

That includes:

  • which decoders are enabled
  • decoding speed
  • resolution
  • whether continuous scanning is enabled
  • whether ROI is enabled
  • AR-specific defaults

For example, VIN mode turns on a narrower ROI and VIN restrictions:

barkoderView.setEnableVINRestrictions(true);
barkoderView.setRegionOfInterest(ROI_VIN.x, ROI_VIN.y, ROI_VIN.width, ROI_VIN.height);

DPM mode enables Data Matrix DPM behavior:

barkoderView.setDatamatrixDpmModeEnabled(true);
barkoderView.setRegionOfInterest(ROI_DPM.x, ROI_DPM.y, ROI_DPM.width, ROI_DPM.height);
01
01

AR mode applies Barkoder AR configuration through dedicated SDK methods:

  • setBarkoderARMode
  • setBarkoderARLocationType
  • setBarkoderARHeaderShowMode
  • setBarkoderARoverlayRefresh
  • setARDoubleTapToFreezeEnabled

This keeps the scanner page generic while still supporting highly specialized scanning flows.

Handling scan results

Results are processed in one place: startScanning() inside app/scanner/scanner-page.ts.

When valid results arrive, the app:

  • pauses scanning in non-continuous flows
  • stores the scanned items
  • saves thumbnails or result images to history
  • updates the result sheet
  • shows a frozen image overlay when scanning is paused

This gives the app a more product-like experience than immediately continuing scanning after every decode.

image
image

NativeScript gallery image scanning

Gallery scanning is implemented differently from the live scanner flow.

The home page includes a hidden 1x1 Barkoder view:

<Barkoder:LicensedBarkoderView
  id="galleryBarkoderView"
  width="1"
  height="1"
  left="-10"
  top="-10"
  opacity="0" />

That hidden view is used only for image-based scanning.

The gallery flow in app/home/home-page.ts does this:

  1. opens the picker with @nativescript/imagepicker
  2. loads the selected image as an ImageSource
  3. converts it to base64
  4. applies a gallery-specific Barkoder config
  5. calls galleryBarkoderView.scanImage(...)
  6. saves results to history
  7. opens details or history depending on result count

The core image-scan call looks like this:

galleryBarkoderView.scanImage(base64Image, {
  scanningFinished(results) {
    ...
  },
});

This is a useful pattern because it keeps gallery scanning separate from the live camera screen while still reusing the same SDK.

Runtime scanner controls

The live scanner page supports runtime controls for:

  • flash
  • zoom
  • front/back camera
  • continuous scanning
  • duplicate threshold
  • decoding speed
  • resolution
  • ROI visibility
  • barcode type toggles
  • AR settings

These settings are rendered dynamically in the settings overlay and applied back into Barkoder through applyScannerConfiguration().

The scanner also supports:

  • copying scanned results
  • sharing CSV output
  • expanding and collapsing the result sheet
  • pausing and resuming scanning

Persistent settings and history

This NativeScript app persists data differently from the Cordova and Capacitor versions.

Per-mode settings are stored using ApplicationSettings in app/services/settings-service.ts.

Scan history is stored as a JSON file in the documents folder, and saved scan images are written into a dedicated scan_images folder through app/services/history-service.ts.

That means this build keeps:

  • timestamped scan history
  • repeated-scan counts
  • stored thumbnail or result images

The history service also deduplicates by text + type, updating existing entries instead of creating noisy duplicates.

02
02

Native platform details

Because this is a NativeScript app, it runs as a real native mobile application rather than a web shell.

Android permissions are declared in App_Resources/Android/src/main/AndroidManifest.xml, including:

  • android.permission.CAMERA
  • android.permission.READ_MEDIA_IMAGES
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.WRITE_EXTERNAL_STORAGE

iOS usage strings are defined in App_Resources/iOS/Info.plist, including camera and photo library access descriptions.

These permissions are required because the app supports both live camera scanning and gallery image scanning.

Performance notes

A few design choices in this project help scanner behavior on-device:

  • ROI is used for specialized modes such as VIN, DPM, MRZ, and DotCode
  • MultiScan enables result caching
  • gallery mode uses more aggressive decoding defaults
  • image results and thumbnails are enabled so the UI can show saved previews
  • scanner settings are restored per mode instead of forcing one global configuration

If you adapt this app for production, those mode-level settings are the first place to tune for your own scanning environment.

Conclusion

barkoder_app_nativeScript shows how to integrate the barKoder SDK into a full NativeScript application instead of a minimal sample.

The most useful implementation patterns here are:

  • wrapping license setup in a custom LicensedBarkoderView
  • keeping scanner configuration mode-aware
  • using a hidden Barkoder view for gallery scanning
  • storing history and images in the device file system
  • separating UI layout in XML from scanner behavior in TypeScript

If you are building with NativeScript and need enterprise-grade barcode scanning, this project is a practical base for a production-style Barkoder integration.

Resources

Frequently Asked Questions

Latest Barcode Scanner SDK Articles,
Tutorials, and News

recentArticle

AAMVA PDF417 Barcode Format: Fields, Examples and Parsing Guide

Every day, millions of state-issued driver's licenses and ID cards are scanned at retail checkouts, airport security checkpoints, bank onboarding desks, and hotel reception counters. Behind nearly all of these physical identity verifications is a two-dimensional barcode printed on the back of the card: the AAMVA-compliant PDF417 barcode.

Aug 14, 2026

Info

recentArticle

30+ Shocking UPC/EAN Code Statistics You Need to Know in 2026

UPC and EAN barcodes remain the backbone of global retail in 2026, powering billions of product scans every day. From supermarkets and warehouses to e-commerce and mobile shopping apps, these standardized barcodes enable fast checkouts, accurate inventory management, and seamless product identification. Discover 30+ surprising UPC/EAN statistics and fun facts that highlight why barcode technology continues to drive modern commerce.

Aug 07, 2026

Info

recentArticle

Why Coca-Cola, PepsiCo, and Red Bull Must Add QR Codes to Every Can by the End of 2027

By the end of 2027, many leading beverage brands, including Coca-Cola, PepsiCo, and Red Bull, are adopting QR codes and other 2D barcodes as part of the GS1 Sunrise 2027 initiative. These digital codes go beyond traditional barcodes by enabling faster retail operations while giving consumers instant access to product information, nutrition facts, recycling guidance, authenticity verification, promotions, and sustainability details with a simple smartphone scan.

Aug 04, 2026

Info