npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

asn1-per-ts

v1.4.0

Published

PER (Packed Encoding Rules) unaligned encoder/decoder for ASN.1 types in TypeScript

Readme

asn1-per-ts

npm

TypeScript library for encoding and decoding data using ASN.1 PER (Packed Encoding Rules) unaligned variant (ITU-T X.691).

Features

  • Bit-level buffer with MSB-first encoding and automatic growth
  • Primitive codecs: BOOLEAN, INTEGER, ENUMERATED, BIT STRING, OCTET STRING, IA5String, VisibleString, UTF8String, NULL
  • Composite codecs: CHOICE, SEQUENCE, SEQUENCE OF
  • Constraint support: value ranges, size constraints, extensibility markers, default values
  • Schema-driven encoding: define types as JSON, encode/decode plain objects
  • Metadata decoding: decodeWithMetadata returns a tree of DecodedNode objects with bit positions, raw bytes, and codec references for every field

Install

npm install asn1-per-ts

Usage

Low-level codec API

import { BitBuffer, IntegerCodec, BooleanCodec, SequenceCodec } from 'asn1-per-ts';

// Constrained integer (0..255) uses 8 bits
const intCodec = new IntegerCodec({ min: 0, max: 255 });

const buf = BitBuffer.alloc();
intCodec.encode(buf, 42);
buf.reset();
console.log(intCodec.decode(buf)); // 42

Schema-driven API

import { SchemaCodec } from 'asn1-per-ts';

const codec = new SchemaCodec({
  type: 'SEQUENCE',
  fields: [
    { name: 'id', schema: { type: 'INTEGER', min: 0, max: 255 } },
    { name: 'active', schema: { type: 'BOOLEAN' } },
    { name: 'status', schema: { type: 'ENUMERATED', values: ['pending', 'approved', 'rejected'] } },
  ],
});

const hex = codec.encodeToHex({ id: 42, active: true, status: 'approved' });
console.log(hex);

const decoded = codec.decodeFromHex(hex);
console.log(decoded);

Decoding with Metadata

decodeWithMetadata returns a DecodedNode tree with full encoding metadata (bit offsets, bit lengths, raw bytes, codec references) for every field. Use stripMetadata to convert back to a plain object identical to decode().

import { SchemaCodec, stripMetadata } from 'asn1-per-ts';
import type { DecodedNode } from 'asn1-per-ts';

const codec = new SchemaCodec({
  type: 'SEQUENCE',
  fields: [
    { name: 'id', schema: { type: 'INTEGER', min: 0, max: 255 } },
    { name: 'active', schema: { type: 'BOOLEAN' } },
  ],
});

const hex = codec.encodeToHex({ id: 42, active: true });
const node = codec.decodeFromHexWithMetadata(hex);

// Access field metadata
const fields = node.value as Record<string, DecodedNode>;
console.log(fields.id.value);           // 42
console.log(fields.id.meta.bitOffset);  // 0
console.log(fields.id.meta.bitLength);  // 8
console.log(fields.id.meta.rawBytes);   // Uint8Array([0x2a])

// Strip metadata to get plain object
const plain = stripMetadata(node);
// plain === { id: 42, active: true }

Extension Markers

Extension markers (...) indicate that a type may be extended in future versions, providing forward compatibility. When present, PER encoding includes a 1-bit extension marker prefix (0 = not extended, 1 = extended).

In ASN.1 notation

Use ... to mark a type as extensible in ASN.1 schema text parsed by the built-in parser:

-- SEQUENCE: extension marker separates root fields from extension additions
MessageV1 ::= SEQUENCE {
    id     INTEGER (0..255),
    name   IA5String,
    ...                        -- extensible, no extensions yet
}

MessageV2 ::= SEQUENCE {
    id     INTEGER (0..255),
    name   IA5String,
    ...,                       -- extension marker
    email  IA5String           -- extension addition
}

-- ENUMERATED: extension marker separates root values from extension values
Color ::= ENUMERATED { red, green, blue, ... }
ColorV2 ::= ENUMERATED { red, green, blue, ..., yellow, purple }

-- CHOICE: extension marker separates root alternatives from extension alternatives
Shape ::= CHOICE { circle BOOLEAN, ..., polygon INTEGER }

-- Constraints: extensible constraints allow values outside the root range
FlexInt ::= INTEGER (0..100, ...)
FlexStr ::= OCTET STRING (SIZE (1..50, ...))

In JSON SchemaNode definitions

When building schemas directly as JSON SchemaNode objects, indicate extensibility with these properties:

// SEQUENCE: provide extensionFields (even empty [] to mark as extensible)
const schema: SchemaNode = {
  type: 'SEQUENCE',
  fields: [
    { name: 'id', schema: { type: 'INTEGER', min: 0, max: 255 } },
  ],
  extensionFields: [],  // extensible with no additions yet
};

// ENUMERATED: provide extensionValues
{ type: 'ENUMERATED', values: ['red', 'green'], extensionValues: [] }

// CHOICE: provide extensionAlternatives
{ type: 'CHOICE', alternatives: [...], extensionAlternatives: [] }

// Constrained types: set extensible: true
{ type: 'INTEGER', min: 0, max: 100, extensible: true }
{ type: 'BIT STRING', minSize: 1, maxSize: 50, extensible: true }

Key distinction: providing an empty array (extensionFields: []) marks the type as extensible, while omitting the property entirely (extensionFields: undefined) means the type is not extensible. This matters because extensible types include the 1-bit extension marker in the encoding.

Supported Types

| Type | Description | |------|-------------| | BOOLEAN | Single bit | | INTEGER | Constrained, semi-constrained, or unconstrained | | ENUMERATED | Indexed enumeration with optional extensions | | BIT STRING | Bit sequences with size constraints | | OCTET STRING | Byte sequences with size constraints | | IA5String | ASCII strings with optional alphabet constraints | | VisibleString | Printable strings with optional alphabet constraints | | UTF8String | UTF-8 encoded strings | | NULL | Zero-bit placeholder | | CHOICE | Tagged union of alternatives | | SEQUENCE | Ordered fields with OPTIONAL/DEFAULT support | | SEQUENCE OF | Homogeneous list with size constraints |

Examples

The examples/ directory contains detailed usage guides with code samples:

  • Schema Parser - Parse ASN.1 text notation into SchemaNode definitions, constraint options, extension markers, CLI usage
  • Encoding - Encode JavaScript objects to PER unaligned binary using SchemaCodec or low-level codecs
  • Decoding - Decode PER unaligned binary data back into objects

Sister Project

dosipas-ts — a TypeScript library built on top of asn1-per-ts for encoding and decoding DOSIPAS / ERA electronic ticket data.

Development

npm test          # Run tests
npm run build     # Build library

Website

The website/ directory contains a React + TailwindCSS demo app for interactive ASN.1 PER encoding and decoding.

cd website
npm install
npm run build     # Build for GitHub Pages (uses ./ asset path)
npm run dev       # Development server

License

MIT