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

@smart-science/sdoi

v0.1.0

Published

Normalize DOIs and derive deterministic SIDs

Readme

Test Package Bun Node.js License

SDOI (smart-doi)

Deterministic DOI normalization (ISO 26324) and derivation of 20-character SIDs (Smart IDs).


Installation

# bun
bun add @smart-science/sdoi

# npm
npm install @smart-science/sdoi

Usage

1. Derive an SID: doiToSid(input)

The out-of-the-box function uses @noble/hashes (synchronous, cross-platform). It extracts and normalizes the DOI, hashes its UTF-8 encoding with SHA-256, and returns a 20-character canonical SID:

import { doiToSid } from '@smart-science/sdoi';

doiToSid('https://doi.org/10.1000/182'); // 'SFG9CPDEVTC05D9SZVWM'
doiToSid('doi:10.1000/ABC');             // 'N3C77HSZ53MZRTE0S9Q7'
doiToSid('not a doi');                   // null

Returns null if the input contains no valid DOI.


2. Custom Hash & Zero-Dependency Tree-Shaking

To avoid bundling @noble/hashes in browser bundles or Node.js services, use createDoiToSid or createDoiToSidAsync with your platform's native crypto.

Because package.json specifies "sideEffects": false, modern bundlers (esbuild, Rollup, Vite, Webpack) tree-shake @noble/hashes away completely when doiToSid is not imported.

Node.js / Bun (node:crypto, synchronous)

import { createHash } from 'node:crypto';
import { createDoiToSid } from '@smart-science/sdoi';

const doiToSid = createDoiToSid((text) =>
    createHash('sha256').update(text).digest()
);

doiToSid('https://doi.org/10.1000/ABC'); // 'N3C77HSZ53MZRTE0S9Q7'

Browsers / Web Crypto (crypto.subtle, asynchronous)

import { createDoiToSidAsync } from '@smart-science/sdoi';

const doiToSid = await createDoiToSidAsync((text) =>
    crypto.subtle.digest('SHA-256', new TextEncoder().encode(text))
);

await doiToSid('https://doi.org/10.1000/ABC'); // 'N3C77HSZ53MZRTE0S9Q7'

Both factories run a one-time self-test on creation to ensure the provided function correctly produces SHA-256 digests.


3. Normalize a DOI: normalizeDoi(input, options?)

Normalizes a DOI string or URL according to ISO 26324 and DOI Handbook specifications:

  • Drops leading prose, URLs, and schemes (doi:, https://doi.org/, http://dx.doi.org/).
  • Decodes percent-encoding in one pass (%20 → space, %2F → /).
  • Lowercases Basic Latin A-Z (casing of non-ASCII letters is preserved per spec).
  • Suffix trailing text is preserved without trimming (no lossy URL or bracket stripping).
import { normalizeDoi } from '@smart-science/sdoi';

normalizeDoi('https://doi.org/10.1000/182');                // '10.1000/182'
normalizeDoi('DOI: 10.1000/ABC-Ä');                         // '10.1000/abc-Ä'
normalizeDoi('https://example.com/search?doi=10.1000%2FA'); // '10.1000/a'
normalizeDoi('not-a-doi');                                  // null

Options

import { normalizeDoi, type NormalizeDoiOptions } from '@smart-science/sdoi';

normalizeDoi(input, {
    allowShortDoi: true,       // Accept shortDOIs (e.g. '10/abcde', 'doi.org/abcde'); default: false
    keepCasing: true,          // Keep original uppercase/lowercase; default: false
    keepPercentEncoding: true, // Keep percent-escapes as literal characters; default: false
});

4. Re-exported SID Utilities

All core utilities from @smart-science/sid are re-exported:

import {
    format,         // Format canonical SID to 'XXXX-XXXX-XXXX-XXXX-XXXX'
    fromBytes,      // Derive SID from 90 bits (12+ bytes)
    isFormattedSID, // Strict type guard for formatted SID
    isSID,          // Strict type guard for canonical SID
    parse,          // Forgiving parser and checksum verifier
    verify,         // Boolean checksum verification
} from '@smart-science/sdoi';

TypeScript Types

import type {
    DoiToSid,
    DoiToSidAsync,
    FormattedSID,
    NormalizeDoiOptions,
    Sha256,
    Sha256Async,
    SID,
    SidErrorCode,
    SidResult,
} from '@smart-science/sdoi';

Runtime Support

| Runtime | Versions | |---|---| | Node.js | 22.12 and later (import and require()) | | Bun | 1.3 and later | | Browsers | Current evergreen browsers |


License

Apache-2.0