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

@otplib/plugin-base32-scure

v13.1.1

Published

Base32 plugin for otplib using @scure/base

Readme

@otplib/plugin-base32-scure

Base32 encoding/decoding plugin for otplib using the @scure/base library.

Installation

npm install @otplib/plugin-base32-scure
pnpm add @otplib/plugin-base32-scure
yarn add @otplib/plugin-base32-scure

Overview

This plugin provides Base32 encoding and decoding using @scure/base, a cryptographic library which is audited and has comprehensive TypeScript support.

Usage

Basic Usage

import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";

const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();

// Generate a secret
const secret = generateSecret({ crypto, base32 });

// Generate a token
const token = await generate({
  secret,
  crypto,
  base32,
});

Encoding and Decoding

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";

const base32 = new ScureBase32Plugin();

// Encode binary data to Base32
const data = new Uint8Array([1, 2, 3, 4, 5]);
const encoded = base32.encode(data, { padding: true });
// Output: "AEBAGBAF"

// Decode Base32 string to binary
const decoded = base32.decode("AEBAGBAF");
// Output: Uint8Array [1, 2, 3, 4, 5]

With Custom Options

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";

const base32 = new ScureBase32Plugin();

// Encode without padding
const encoded = base32.encode(data, { padding: false });
// Output: "AEBAGBAF"

// Decode handles both padded and unpadded strings
const decoded1 = base32.decode("AEBAGBAF===="); // With padding
const decoded2 = base32.decode("AEBAGBAF"); // Without padding

When to Use

Use this plugin when:

  • You want an audited, security-focused implementation
  • Performance is critical
  • You need comprehensive input validation
  • You're building security-critical applications
  • You prefer libraries with active maintenance and security audits

Platform Support

Works in all environments:

  • Node.js (all versions)
  • Browsers (Chrome, Firefox, Safari, Edge)
  • Edge runtimes (Cloudflare Workers, Vercel Edge)
  • Deno
  • Bun

Examples

TOTP with Scure Base32

import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";

const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();

const secret = generateSecret({ crypto, base32 });
console.log(secret); // Base32-encoded secret

const token = await generate({ secret, crypto, base32 });
console.log(token); // 6-digit token

Web Environment

import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";

const base32 = new ScureBase32Plugin();
const crypto = new WebCryptoPlugin();

const secret = await generateSecret({ crypto, base32 });
const token = await generate({ secret, crypto, base32 });

Manual Secret Generation

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";

const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();

// Generate random secret
const secretBytes = crypto.randomBytes(20);
const secret = base32.encode(secretBytes, { padding: false });

console.log(secret); // Base32 secret for TOTP

Edge Runtime (Cloudflare Worker)

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";

export default {
  async fetch(request) {
    const base32 = new ScureBase32Plugin();
    const crypto = new WebCryptoPlugin();

    // Generate secret
    const secretBytes = await crypto.randomBytes(20);
    const secret = base32.encode(secretBytes, { padding: false });

    return new Response(JSON.stringify({ secret }));
  },
};

Advanced Usage

Custom Validation

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";

const base32 = new ScureBase32Plugin();

function validateAndDecode(input: string): Uint8Array | null {
  try {
    // @scure/base validates:
    // - Character set (A-Z, 2-7)
    // - Length (must be multiple of 8 with padding, or correct without)
    // - Padding (if present, must be correct)
    return base32.decode(input);
  } catch (error) {
    console.error("Invalid Base32:", error.message);
    return null;
  }
}

const valid = validateAndDecode("JBSWY3DPEHPK3PXP");
const invalid = validateAndDecode("invalid@base32!");

Integration with Other Libraries

import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { base32 as scureBase32 } from "@scure/base";

const plugin = new ScureBase32Plugin();

// Use plugin's convenience methods
const encoded = plugin.encode(data);

// Or use @scure/base directly for advanced options
const encoded = scureBase32.encode(data, { padding: false });

Related Packages

  • @scure/base - Audited encoding/decoding library
  • @otplib/core - Core types and interfaces
  • @otplib/plugin-crypto-node - Node.js crypto plugin
  • @otplib/plugin-crypto-web - Web Crypto API plugin

Documentation

Full documentation available at otplib.yeojz.dev:

License

MIT © 2026 Gerald Yeo