
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@otplib/uri
Advanced tools
Parse and generate otpauth:// URIs for OTP account provisioning.
npm install @otplib/uri
pnpm add @otplib/uri
yarn add @otplib/uri
The @otplib/uri package provides utilities for working with otpauth:// URIs - the standard format for sharing OTP account information. These URIs are commonly used in QR codes for authenticator app setup.
otpauth://TYPE/LABEL?PARAMETERS
totp or hotpissuer:account or just accountsecret, issuer, algorithm, digits, period/counterExample:
otpauth://totp/GitHub:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub
import { parse } from "@otplib/uri";
const uri = "otpauth://totp/GitHub:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub";
const result = parse(uri);
console.log(result);
// {
// type: 'totp',
// label: 'GitHub:user@example.com',
// params: {
// secret: 'JBSWY3DPEHPK3PXP',
// issuer: 'GitHub',
// algorithm: 'sha1',
// digits: 6,
// period: 30
// }
// }
import { parse } from "@otplib/uri";
const uri = "otpauth://totp/ACME%20Corp:john@example.com?secret=JBSWY3DPEHPK3PXP";
const { label, params } = parse(uri);
// Split label to get issuer and account
const [issuer, account] = label.includes(":") ? label.split(":") : [params.issuer, label];
console.log("Issuer:", issuer); // 'ACME Corp'
console.log("Account:", account); // 'john@example.com'
console.log("Secret:", params.secret);
import {
parse,
URIParseError,
InvalidURIError,
MissingParameterError,
InvalidParameterError,
} from "@otplib/uri";
try {
const result = parse("invalid-uri");
} catch (error) {
if (error instanceof InvalidURIError) {
console.error("Not a valid otpauth:// URI");
} else if (error instanceof MissingParameterError) {
console.error("Missing required parameter (e.g., secret)");
} else if (error instanceof InvalidParameterError) {
console.error("Invalid parameter value");
}
}
import { generateTOTP } from "@otplib/uri";
const uri = generateTOTP({
issuer: "ACME Corp",
label: "john@example.com",
secret: "JBSWY3DPEHPK3PXP",
});
console.log(uri);
// 'otpauth://totp/ACME%20Corp:john@example.com?secret=JBSWY3DPEHPK3PXP&issuer=ACME%20Corp'
import { generateTOTP } from "@otplib/uri";
const uri = generateTOTP({
issuer: "GitHub",
label: "user@github.com",
secret: "JBSWY3DPEHPK3PXP",
algorithm: "sha256", // Non-default algorithm
digits: 8, // 8-digit tokens
period: 60, // 60-second period
});
import { generateHOTP } from "@otplib/uri";
const uri = generateHOTP({
issuer: "MyApp",
label: "user123",
secret: "JBSWY3DPEHPK3PXP",
counter: 0, // Starting counter
});
console.log(uri);
// 'otpauth://hotp/MyApp:user123?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&counter=0'
For more control, use the generate function directly:
import { generate } from "@otplib/uri";
const uri = generate({
type: "totp",
label: "CustomApp:user@example.com",
params: {
secret: "JBSWY3DPEHPK3PXP",
issuer: "CustomApp",
algorithm: "sha1",
digits: 6,
period: 30,
},
});
::: warning Google Authenticator Limitations Google Authenticator has specific requirements:
sha1 algorithm6 or 8 digits30 second period for TOTPimport { generateTOTP } from "@otplib/uri";
// This URI is fully compatible with Google Authenticator
const uri = generateTOTP({
issuer: "MyService",
label: "user@example.com",
secret: "JBSWY3DPEHPK3PXP",
// algorithm: 'sha1', // Default, compatible
// digits: 6, // Default, compatible
// period: 30, // Default, compatible
});
Generate a QR code for the URI using any QR library:
import { generateTOTP } from "@otplib/uri";
import QRCode from "qrcode"; // Example library
const uri = generateTOTP({
issuer: "MyApp",
label: "user@example.com",
secret: "JBSWY3DPEHPK3PXP",
});
// Generate QR code as data URL
const qrDataUrl = await QRCode.toDataURL(uri);
// Or generate as SVG
const qrSvg = await QRCode.toString(uri, { type: "svg" });
Full documentation available at otplib.yeojz.dev:
MIT © 2026 Gerald Yeo
FAQs
otpauth:// URI parsing and generation for otplib
The npm package @otplib/uri receives a total of 995,711 weekly downloads. As such, @otplib/uri popularity was classified as popular.
We found that @otplib/uri demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.