ASN1.js

A pure JavaScript/TypeScript library for encoding and decoding ASN.1 BER/DER data, the foundation of X.509 certificates and PKI.

Library
npm
v3.0.10
299stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
79/100Good
Development Activity92
Maintenance68
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture85
Code Quality85
Innovation70
Learning Curve75

asn1js is a pure JavaScript/TypeScript implementation of ASN.1 Basic Encoding Rules (BER) and Distinguished Encoding Rules (DER), the notation and wire format underlying X.509 certificates, PKI structures, and many telecommunications and networking protocols. It runs unmodified in both the browser and Node.js by working directly against ArrayBuffer/Uint8Array, and it exposes both a full object model for constructing ASN.1 structures programmatically and a decoder for parsing existing BER/DER-encoded byte streams back into typed, named sub-blocks.

Beyond raw encode/decode, the library ships a schema-validation layer (verifySchema/compareSchema) so callers can describe an expected ASN.1 structure once and validate incoming data against it in a single call, plus automatic conversion between ASN.1 string/date-time types and native JavaScript String/Date values. It serves as the base layer for PKIjs, and recent releases add explicit maxDepth/maxNodes/maxContentLength limits on fromBER() to safely bound parsing of untrusted, potentially adversarial input.

What You Get

  • A full ASN.1 BER decoder (fromBER) and encoder (toBER) covering every ASN.1:2008 universal type (Sequence, Set, Integer, BitString, OctetString, ObjectIdentifier, UTCTime, GeneralizedTime, and all string/date-time variants)
  • A schema-validation layer (verifySchema, compareSchema) to declare an expected ASN.1 shape and validate/extract named sub-blocks in one call instead of manually walking a decoded tree
  • Automatic two-way conversion between ASN.1 string and date-time types and native JavaScript String/Date values
  • Byte-level access to every decoded sub-block (tag block, length block, value block) for low-level inspection or manipulation
  • Resource-limit options (maxDepth, maxNodes, maxContentLength) on the decoder to safely bound parsing of untrusted BER input
  • Dual CommonJS/ESM builds with bundled TypeScript type definitions, usable in both browser and Node.js

Common Use Cases

  • Parsing and validating X.509 certificates, CSRs, and other PKI structures in a Node.js or browser application
  • Building or inspecting cryptographic protocol messages (e.g. CMS/PKCS structures) as a dependency of higher-level libraries like PKIjs
  • Implementing custom ASN.1-based protocol parsers where a schema can describe the expected structure up front
  • Safely decoding untrusted, externally supplied BER/DER byte streams with explicit depth/node/size limits
  • Converting between raw DER bytes and human-inspectable JavaScript objects for debugging or tooling

Under The Hood

Architecture parser.ts’s fromBER/localFromBER dispatches on ASN.1 tag class and tag number through a TypeStore registry (typeStore.Sequence, typeStore.Integer, typeStore.BitString, etc.) to convert a generic BaseBlock into the correct specific ASN.1 type, recursively decoding constructed types depth-first while threading a FromBerContext that tracks depth/node-count/content-length for resource-limit enforcement. Every block composes an identification block (idBlock), a length block (lenBlock), and a type-specific value block (e.g. LocalIntegerValueBlock, LocalBitStringValueBlock under src/internals/), each implementing its own fromBER/toBER; shared byte-level helpers live in HexBlock and LocalBaseBlock so higher-level types like Sequence, Set, and Choice compose the Constructed/Primitive base classes rather than reimplementing BER framing themselves.

Tech Stack Pure TypeScript in strict mode targeting ES2019, built with Rollup (rollup-plugin-typescript2 and rollup-plugin-dts) into dual CommonJS and ESM bundles (build/index.js, build/index.es.js) plus a bundled index.d.ts. Runtime dependencies are minimal — pvtsutils and pvutils for buffer/view conversion, tslib for TypeScript helper injection — with no framework and no Node-only APIs, so the same build runs in browsers and Node against native ArrayBuffer/Uint8Array.

Code Quality Tests live under test/ (testSuite.spec.ts, unitTests.spec.ts, types.spec.ts) and run under Vitest with v8 coverage across text/html/clover/json/lcov reporters; a companion asn1-test-suite dev dependency runs the library against a published ASN.1:2008 conformance corpus. oxlint and oxfmt enforce linting and formatting in CI (test.yml), and decode errors are returned as typed FromBerResult objects (offset -1 plus a populated .error string) rather than thrown, giving callers explicit control flow instead of try/catch around parsing.

API Design The public surface centers on two calls — fromBER() to decode and an instance’s toBER() to encode — plus the schema layer (verifySchema/compareSchema), which lets callers declare an expected ASN.1 shape once and validate/extract named sub-blocks in a single pass instead of walking a decoded tree by hand. ASN.1 string and date-time types convert transparently to and from native JavaScript String/Date on construction and access, removing manual encoding-table lookups from typical call sites, and a recent addition exposes maxDepth/maxNodes/maxContentLength options on fromBER specifically to bound resource use when parsing untrusted input.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search