A small CLI for working with Thai QR (TLV) data. The npm package name is thaiqr-cli, but the installed command is thaiqr.
Implemented in TypeScript and designed to run with Bun (also works with Node.js when using Bun-compatible commands).
- Bun — https://bun.sh (recommended)
- Node.js (for users who prefer Node; see notes below)
- TypeScript ^5 (peer dependency)
Install the published CLI from npm (recommended for users):
# install globally
npm install -g thaiqr-cli
# or run with npx without installing globally
npx thaiqr-cli decode "000201..."If you're developing the project or want to run locally from source, install dependencies with Bun:
bun installIf you prefer to use npm or yarn for development, install dependencies with your package manager of choice. Some scripts assume Bun; see "Running without Bun" below.
After installing the package from npm you can run the CLI as the thaiqr command.
Usage:
thaiqr [decode | encode | generate] [<arg> | <file> | -] [flags]decode [<payload> | <file> | -] [--force]— decode a TLV payload string, file, or stdin to outline.--forcebypasses CRC validation when decoding (use with caution).
encode [<outline> | <file> | -] [--preserve-crc]— encode an outline string, file, or stdin to TLV payload.--preserve-crcwill keep any CRC present in the outline instead of recomputing it.
generate [<payload> | <file> | -]— generate an ASCII QR from a payload string, file, or stdin.
Notes on inputs
-forces reading from stdin.- If the argument is an existing file path the file is read.
- If an argument is given and it's not a file, it is treated as a raw data string.
- If no argument is given and stdin is piped, the CLI reads from stdin.
Examples:
Once installed from npm you can run the following directly with the installed binary:
# decode a TLV payload string (verifies CRC by default)
thaiqr decode "000201..."
# decode a TLV payload string and ignore CRC errors
thaiqr decode "000201..." --force
# decode a TLV payload from a file
thaiqr decode path/to/payload.txt
# decode a TLV payload from stdin
cat payload.txt | thaiqr decode -
# encode an outline file into a Thai QR payload (CRC recomputed)
thaiqr encode path/to/outline.txt
# encode an outline but preserve an existing CRC field
thaiqr encode path/to/outline.txt --preserve-crc
# encode an outline from stdin
cat outline.txt | thaiqr encode -
# encode an outline string directly
thaiqr encode "00: 01\n01: 02\n..."
# generate a QR directly from a payload string
thaiqr generate "000201..."
# generate a QR from a file
thaiqr generate path/to/payload.txt
# generate a QR from stdin
cat payload.txt | thaiqr generate -Scripts from package.json:
build— compile and bundle the CLI using Bun; outputs todist/thaiqr.js.decode— (development script) runsrc/index.tsin decode mode.encode— (development script) runsrc/index.tsin encode mode.generate— (development script) runsrc/index.tsin generate mode.test— run the project's tests with Bun.
Running without Bun (Node.js users / developers):
- Install dependencies with npm/yarn.
- Build the bundle with Bun (recommended for development):
bun run build. The produced bundle isdist/thaiqr.js. - For local testing you can run the lightweight wrapper which will prefer the built bundle and fall back to source when available:
# run the local wrapper (development-only)
node bin/thaiqr --helpFor end users, there is no need to run node dist/thaiqr.js or bun run decode — install the package from npm and use the thaiqr command instead.
- Source files live in
src/and tests are insrc/*.test.ts. - The project is configured as an ESM module and uses TypeScript. The
buildscript uses Bun to produce a single JS bundle indist/.
Decode a TLV payload and print the human-readable outline:
bun run decode "000201..."
bun run decode path/to/payload.txt
cat payload.txt | bun run decode -Encode an outline file or string into a Thai QR payload:
bun run encode ./examples/example-outline.txt
bun run encode "00: 01\n01: 02\n..."
cat outline.txt | bun run encode -Generate an ASCII QR directly from a payload string or file:
bun run generate "000201..."
bun run generate path/to/payload.txt
cat payload.txt | bun run generate -Outline is the format I came up with to clearly list all tags and values found in a Thai QR code. In this format, each tag and its value appear on their own line, and tags can be nested under other tags. For each level of nesting, use three spaces for indentation. The meaning of each tag number and its specification can be found in the Thai QR Code Payment Standard.
Example:
00 01
01 12
30
00 A000000677010112
01 099400000000000
02 M000000000
03 T000A000000000000000
53 764
58 TH
63 BCCE
- Open an issue or PR for bugs and feature requests.
- Keep tests passing (
bun run test) for any changes.
This project is licensed under the Apache License 2.0. See the
LICENSE file for the full text.
Attribution: this project includes code adapted from qrcode-terminal (https://github.com/gtanner/qrcode-terminal). See https://github.com/gtanner/qrcode-terminal/blob/master/LICENSE for the original license and copyright information.