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

strong-type

v2.0.2

Published

Dependency-free native ESM type enforcement for JavaScript values, objects, classes, browsers, and Node.

Readme

strong-type JavaScript values passing through a native type-validation gate

strong-type

Overview · Validator reference · Tests & coverage · Playground

npm version Node support CI license runtime dependencies

Native type enforcement for JavaScript. strong-type runs as the same untransformed ES module in browsers and Node. Strict checks throw a useful TypeError; non-strict checks return a boolean.

Native by design

| Property | Guarantee | What it means | |---|---|---| | Module format | Native ESM | The checked-in JavaScript is what the runtime executes. | | Runtime dependencies | None | No third-party production packages. | | Development dependencies | vanilla-test 2.1.0 | The exact test-runner pin is development-only; runtime installs remain dependency-free. | | Bundler | Not required | Browser and Node imports work directly. | | Transpiler | Not required | No generated CommonJS or compatibility copy. | | Default entry point | Isomorphic | index.js contains no node:* imports. | | Node support | Explicit adapter | strong-type/node adds Node-only precision checks. | | Extensibility | Exported Is class | Custom validators work directly and in unions. |

Install

npm install strong-type

| Import | Runtime | Contents | Build required | |---|---|---|---| | strong-type | Browser + Node | All isomorphic and guarded host validators | No | | strong-type/index.js | Browser + Node | Compatibility path to the same core | No | | strong-type/node | Node | Core plus Node built-ins and exact util.types checks | No | | strong-type/node.js | Node | Compatibility path to the Node adapter | No |

Quick start

import Is from 'strong-type';

const is=new Is;
const weakIs=new Is(false);

is.string('strong-type');        // true
weakIs.number('42');             // false
is.union(new Map,'map|set');     // true

is.number('42');                 // throws TypeError

Strict and non-strict modes

| Mode | Create | Passing check | Failing check | Best use | |---|---|---|---|---| | Strict | new Is or new Is(true) | Returns true | Throws TypeError | Contracts and enforcement | | Non-strict | new Is(false) | Returns true | Returns false | Branching and type discovery |

Every advertised method exists in every runtime. When a guarded platform capability is unavailable, strict mode throws TypeError and non-strict mode returns false. Missing APIs never leak a ReferenceError.

Validator reference

The default isomorphic entry exposes 183 validators. The Node adapter adds 18, for 201 documented validators total. The website reference gives every method its own searchable row with an example, edge case, and runtime label.

Values, primitives, and numbers

| Methods | What passes | Important detail | |---|---|---| | defined, any, exists | Anything except undefined | null is defined. | | null | Exactly null | No loose comparison; undefined fails. | | nullish | null or undefined | Other falsy values fail. | | undefined | Exactly undefined | null fails. | | boolean | Primitive booleans | Boxed Boolean objects fail. | | bigInt, bigint | Primitive bigint values | bigint is the lowercase alias. | | number | Primitive numbers | Includes NaN and infinities. | | finite, finiteNumber | Finite primitive numbers | Strings, null, and BigInt are not coerced. | | integer | Integer primitive numbers | NaN and infinities fail. | | safeInteger | Safe integer primitive numbers | Uses Number.isSafeInteger. | | NaN, nan | Exactly numeric NaN | No string coercion. | | infinity, positiveInfinity | Exactly positive Infinity | infinity keeps its positive-only compatibility meaning. | | negativeInfinity | Exactly negative Infinity | Positive Infinity fails. | | infinite | Either infinity | Finite numbers fail. | | negativeZero | Exactly -0 | Uses Object.is; +0 fails. | | string | Primitive strings | Boxed String objects fail. | | symbol | Primitive symbols | Boxed Symbol objects fail. | | primitive | null or any non-object, non-function value | Boxed primitives and functions fail. | | globalThis | Exactly the current globalThis | Host aliases are not substituted. | | atomics, json, math, reflect | Their exact global namespaces | Identity checks, not lookalike objects. | | rawJSON | Values created by JSON.rawJSON | Guarded until JSON.isRawJSON exists. |

Objects and collections

| Methods | What passes | Important detail | |---|---|---| | array | Arrays from any realm | Uses Array.isArray. | | date | Date objects from any realm | Invalid dates still pass. | | validDate | Dates with a valid time value | Invalid Date fails. | | map, weakMap, set, weakSet | Their matching collection brands | Native internal-slot probes work across realms. | | object | Values where typeof value === 'object' | Compatibility behavior: null passes. | | nonNullObject | Non-null object values | Use this for the ordinary meaning of object. | | plainObject | Plain records, including null-prototype records | Arrays and class instances fail. | | nullPrototypeObject | Objects with an exact null prototype | Ordinary object literals fail. | | argumentsObject | Function arguments objects | Arrays fail. | | promise | Promise instances in the current realm | Structural thenables have a separate check. | | thenable | Objects or functions with a callable then | It never invokes then. | | regExp, regexp | RegExp objects from any realm | regexp is the lowercase-p alias. |

Boxed primitives

| Method | What passes | Primitive near miss | |---|---|---| | boxedPrimitive | Any boxed Boolean, Number, BigInt, String, or Symbol | 1 | | booleanObject | Object(true) | true | | numberObject | Object(1) | 1 | | bigIntObject | Object(1n) | 1n | | stringObject | Object('type') | 'type' | | symbolObject | Object(Symbol('type')) | Symbol('type') |

Functions and protocols

| Methods | What passes | Important detail | |---|---|---| | function, callable | Anything whose typeof is function | Includes async and generator functions. | | asyncFunction | Async functions | Ordinary functions fail. | | generatorFunction | Generator functions | Generator objects use generator. | | asyncGeneratorFunction | Async generator functions | Objects use asyncGenerator. | | generator, asyncGenerator | Their matching generator iterator objects | Function values fail. | | iterator | Values with a callable next | Structural by design. | | asyncIterator | Values with next and Symbol.asyncIterator | Structural by design. | | iterable, asyncIterable | Values with the matching symbol method | Null-safe and getter-safe. |

Errors

| Methods | What passes | Runtime | |---|---|---| | error | Error instances | Shared | | aggregateError | AggregateError instances | Guarded standard | | evalError | EvalError instances | Shared | | rangeError | RangeError instances | Shared | | referenceError | ReferenceError instances | Shared | | syntaxError | SyntaxError instances | Shared | | typeError | TypeError instances | Shared | | URIError, uriError | URIError instances | Shared; lowercase alias included | | suppressedError | SuppressedError instances | Guarded standard |

Typed arrays and buffers

| Methods | What passes | Important detail | |---|---|---| | typedArray | Any typed array | Excludes DataView. | | arrayBufferView | Any typed array or DataView | Uses ArrayBuffer.isView. | | bigInt64Array, bigUint64Array | Matching BigInt typed arrays | Exact brand. | | float16Array | Float16Array | Guarded on older runtimes. | | float32Array, float64Array | Matching float typed arrays | Exact brand. | | int8Array, int16Array, int32Array | Matching signed integer typed arrays | Exact brand. | | uint8Array, uint8ClampedArray, uint16Array, uint32Array | Matching unsigned integer typed arrays | A Node Buffer is also a Uint8Array. | | arrayBuffer | ArrayBuffer | Cross-realm native slot probe. | | sharedArrayBuffer | SharedArrayBuffer | Guarded where shared memory is absent. | | anyArrayBuffer | Either buffer kind | Views fail. | | dataView | DataView | Typed arrays fail. | | resizableArrayBuffer | Resizable ArrayBuffer values | Fixed buffers fail. | | growableSharedArrayBuffer | Growable SharedArrayBuffer values | Fixed shared buffers fail. | | detachedArrayBuffer | Transferred/detached ArrayBuffer values | The fallback probe is non-destructive. |

Intl

| Methods | What passes | Availability | |---|---|---| | intlDateTimeFormat | Intl.DateTimeFormat | Shared | | intlCollator | Intl.Collator | Shared | | intlDisplayNames | Intl.DisplayNames | Guarded | | intlListFormat | Intl.ListFormat | Guarded | | intlLocale | Intl.Locale | Shared | | intlNumberFormat | Intl.NumberFormat | Shared | | intlPluralRules | Intl.PluralRules | Shared | | intlRelativeTimeFormat | Intl.RelativeTimeFormat | Guarded | | intlSegmenter | Intl.Segmenter | Guarded | | intlSegments | Values returned by segmenter.segment() | Guarded | | intlDurationFormat | Intl.DurationFormat | Guarded |

Lifetime, resources, and Temporal

| Methods | What passes | Availability | |---|---|---| | finalizationRegistry | FinalizationRegistry objects | Guarded standard | | weakRef | WeakRef objects | Guarded standard | | disposable | Values with callable Symbol.dispose | Guarded structural protocol | | asyncDisposable | Values with callable Symbol.asyncDispose | Guarded structural protocol | | disposableStack | DisposableStack objects | Guarded standard | | asyncDisposableStack | AsyncDisposableStack objects | Guarded standard | | temporalDuration | Temporal.Duration | Guarded standard | | temporalInstant | Temporal.Instant | Guarded standard | | temporalPlainDate | Temporal.PlainDate | Guarded standard | | temporalPlainDateTime | Temporal.PlainDateTime | Guarded standard | | temporalPlainMonthDay | Temporal.PlainMonthDay | Guarded standard | | temporalPlainTime | Temporal.PlainTime | Guarded standard | | temporalPlainYearMonth | Temporal.PlainYearMonth | Guarded standard | | temporalZonedDateTime | Temporal.ZonedDateTime | Guarded standard |

Shared Web APIs

These methods are present on every Is instance. The constructor or singleton is resolved through globalThis only when the method is called.

| Family | Methods | What passes | |---|---|---| | URL | url, urlSearchParams, urlPattern | Matching URL API objects | | Text | textEncoder, textDecoder, textEncoderStream, textDecoderStream | Encoding API objects | | Data | domException, blob, file, formData, headers, request, response | Matching Fetch/data objects | | Cancellation | abortController, abortSignal | Matching cancellation objects | | Events | event, eventTarget, customEvent, messageEvent, closeEvent, errorEvent | Matching event objects | | Messaging | broadcastChannel, messageChannel, messagePort, webSocket, eventSource | Matching communication objects | | Host values | navigator, storage | The current navigator or a Storage object | | Readable streams | readableStream, readableStreamDefaultReader, readableStreamBYOBReader, readableStreamDefaultController, readableByteStreamController, readableStreamBYOBRequest | Matching Web Streams objects | | Writable streams | writableStream, writableStreamDefaultWriter, writableStreamDefaultController | Matching Web Streams objects | | Transform streams | transformStream, transformStreamDefaultController | Matching transform objects | | Queuing | byteLengthQueuingStrategy, countQueuingStrategy | Matching strategy objects | | Compression | compressionStream, decompressionStream | Matching compression objects | | Crypto | crypto, subtleCrypto, cryptoKey | Current crypto services and keys | | Performance | performance, performanceEntry, performanceMark, performanceMeasure, performanceObserver, performanceObserverEntryList, performanceResourceTiming | Matching performance objects | | WebAssembly | webAssemblyModule, webAssemblyInstance, webAssemblyMemory, webAssemblyTable, webAssemblyGlobal, webAssemblyTag, webAssemblyException, webAssemblyCompileError, webAssemblyLinkError, webAssemblyRuntimeError | Matching WebAssembly objects and errors |

Core and extension methods

| Method | Result | Purpose | |---|---|---| | throw(valueType,expectedType) | false or throws | Central strict/non-strict failure behavior. | | check(value,pass,expectedType) | true, false, or throws | Turn a predicate into strong-type behavior. | | typeCheck(value,type) | true, false, or throws | Validate a typeof result. | | instanceCheck(value,constructor) | true, false, or throws | Validate a custom class or realm-local constructor. | | symbolStringCheck(value,type) | true, false, or throws | Validate an intrinsic object tag. | | compare(value,target,typeName) | true, false, or throws | Compare exact identity with Object.is. | | globalInstanceCheck(value,type) | true, false, or throws | Guard and check a named global constructor. | | nestedInstanceCheck(value,container,type) | true, false, or throws | Guard and check a constructor inside a namespace. | | globalValueCheck(value,type) | true, false, or throws | Check exact identity with a named global value. | | nestedValueCheck(value,container,type) | true, false, or throws | Check exact identity with a nested value. | | union(value,types) | true, false, or throws | Accept one named validator from a pipe string or array. |

Unions

is.union('type','string|number');
is.union(42,['string','number']);

| Behavior | Result | |---|---| | Whitespace around pipe names | Trimmed | | Matching validator | Called once | | Custom subclass validator | Supported | | Node adapter validator | Supported through IsNode | | Inherited Object method such as toString | Rejected | | Multi-argument helper method | Rejected |

Node adapter

import IsNode from 'strong-type/node';

const is=new IsNode;

is.buffer(Buffer.from('type'));
is.proxy(new Proxy({},{}));
is.nodeReadable(process.stdin);

The adapter imports Node built-ins only. It never enters the default browser-safe import graph.

| Method | What passes | Important detail | |---|---|---| | buffer | Node Buffer values | A plain Uint8Array fails. | | nodeStream | Any classic Node Stream | Web Streams use the shared validators. | | nodeReadable | Node Readable streams | Duplex and Transform inherit Readable. | | nodeWritable | Node Writable streams | Duplex and Transform inherit Writable. | | nodeDuplex | Node Duplex streams | Plain readable or writable streams fail. | | nodeTransform | Node Transform streams | PassThrough inherits Transform. | | nodePassThrough | Node PassThrough streams | Other transforms fail. | | eventEmitter | Node EventEmitter instances | DOM EventTarget fails. | | timeout | Handles returned by setTimeout | Constructor is discovered lazily. | | immediate | Handles returned by setImmediate | Constructor is discovered lazily. | | keyObject | Node crypto KeyObject values | Web CryptoKey uses cryptoKey. | | x509Certificate | Node X509Certificate objects | Requires a parseable certificate. | | proxy | Proxy values | Exact util.types.isProxy check. | | moduleNamespaceObject | Results from import() | Exact util.types check. | | external | Native external values | Usually supplied by a native addon. | | nativeError | Native Error values | Includes cross-realm errors. | | mapIterator | Native Map iterators | Set iterators fail. | | setIterator | Native Set iterators | Map iterators fail. |

Direct browser use without bundling

strong-type works with bundlers and without a bundler. Bundlers resolve the bare strong-type import normally. Native browser ESM resolves that same bare import through an import map, with no build or transpilation step.

For the normal npm layout, place this complete import map before the module script:

<script type="importmap">
    {
        "imports": {
            "strong-type": "./node_modules/strong-type/index.js"
        }
    }
</script>

<script type="module">
    import Is from 'strong-type';

    const is=new Is;
    console.log(is.url(new URL('https://example.com')));
</script>

Import-map paths are relative to the HTML document. Serve the app over HTTP(S), and configure the server to expose the mapped node_modules file; file:// is not a supported module-loading path. strong-type has zero runtime dependencies, so there are no dependency entries or nested-version scopes to add.

You can also import the source directly in a native module script:

<script type="module">
    import Is from 'https://riaevangelist.github.io/strong-type/index.js';

    const is=new Is;
    console.log(is.string('native ESM'));
</script>

Use your own hosted path instead of the project Pages URL when you want to serve the file yourself. No bundle, transform, runtime shim, or host switch is involved.

Extend strong-type

import Is from 'strong-type';

class Pizza{}

class MyIs extends Is{
    pizza(value){
        return this.instanceCheck(value,Pizza);
    }
}

const is=new MyIs;

is.pizza(new Pizza);
is.union(new Pizza,'pizza|string');

| Extension helper | Use | |---|---| | this.typeCheck(value,'string') | Custom typeof validator | | this.instanceCheck(value,Pizza) | Custom class validator | | this.check(value,predicate,'description') | Any custom predicate with standard strict behavior | | this.throw(actual,expected) | Explicit failure path |

Corrected exact behavior

Version 2 removes several coercive edge cases while retaining the original method names.

| Check | Old behavior | Current behavior | |---|---|---| | null(undefined) | Passed through loose equality | Fails | | infinity('Infinity') | Passed through loose equality | Fails | | finite('1') | Passed through global coercive isFinite | Fails | | finite(null) | Passed through coercion | Fails | | finite(1n) | Could leak a native error | Returns false or throws strong-type TypeError | | union(value,' string \| number ') | Did not trim names | Works | | union(value,'toString') | Could call an inherited method | Rejected | | Subclass validators in union | Lost by constructing base Is | Preserved |

Core benchmarks

The dependency-free benchmark runner measures representative successful and rejecting core validator paths with rotating fixtures, calibrated samples, result verification, dedicated per-case loops, median timings, and median absolute deviation.

npm run benchmark
npm run benchmark:baseline
npm run benchmark:historical

The default command measures the current checkout. benchmark:baseline compares it with the pre-optimization 700059a implementation, while benchmark:historical provides a same-realm throughput reference against 1.1.0. Both comparison commands require a Git checkout containing the referenced commits. Absolute timings are harness-specific JIT throughput references, and historical results are informational because 1.1.0 did not provide the current cross-realm and spoof-resistance guarantees.

Tests and coverage

One canonical registry runs through vanilla-test 2.1.0 on Node 22.12 or newer, with every expectation assigned once to Unit, Functional, Behavioral, Integration, or Regression. CI exercises both the minimum VanillaTest runtime and Node 24. Older supported Node releases run that same registry through the small dependency-free compatibility adapter, so the development runner does not change the package's runtime support or add production dependencies.

| Test suite | Result on Node 24.18.0 | Covers | |---|---:|---| | Unit | 586 passed · 13 guarded skips | Atomic validator contracts across all 201 core and Node validators, including guarded capabilities | | Functional | 15 passed | Strict and non-strict modes, unions, custom validators, and Node adapter inheritance | | Behavioral | 8 passed | Consumer order boundaries, untrusted JSON filtering, identifier routing, domain extensions, Node uploads, and thenable safety | | Integration | 636 passed | Reference and README completeness, browser-resolution contracts, site links, package exports, packed-consumer configuration, and CI wiring | | Regression | 23 passed | Coercion fixes, cross-realm brands, spoof resistance, revoked proxies, and cleanup resilience | | Total | 1,268 passed · 0 failed · 13 skipped | Five exclusive suites from one non-duplicative registry, plus the same seven shared behavioral scenarios passing in Node and Chrome |

A guarded skip means the runtime does not expose that host API. It is a capability result, not an ignored failure.

Coverage uses VanillaTest's native Node V8 collector and includes only the two shipped runtime sources. Its executable-range and block-range metrics come directly from V8 and are not interchangeable with parser-derived statement or branch percentages.

| Source | Executable ranges | Block ranges | Function ranges | Executable lines | |---|---:|---:|---:|---:| | index.js | 90.00% · 306/340 | 71.05% · 81/114 | 99.55% · 225/226 | 90.87% · 926/1019 | | node.js | 88.23% · 30/34 | 80.00% · 8/10 | 91.66% · 22/24 | 91.91% · 91/99 | | Total | 89.83% · 336/374 | 71.77% · 89/124 | 98.80% · 247/250 | 90.96% · 1017/1118 |

| Per-file gate | Lowest current file | Required | |---|---:|---:| | Executable ranges | 88.23% | 85% | | Block ranges | 71.05% | 65% | | Function ranges | 91.66% | 90% | | Executable lines | 90.87% | 90% |

Test and documentation files are excluded from the percentages. See the full test, coverage, and CI explanation.

Commands

| Command | What it does | Third-party tooling | |---|---|---| | npm run benchmark | Measures current core validator throughput with verified results and dispersion | None | | npm run benchmark:baseline | Compares current core throughput with pre-optimization commit 700059a | Git | | npm run benchmark:historical | Compares overlapping same-realm paths with 1.1.0 commit 3229b47 | Git | | npm test | Runs Unit, Functional, Behavioral, Integration, and Regression through one registry | vanilla-test 2.1.0 | | npm run test:unit | Runs atomic core and Node validator contracts | vanilla-test 2.1.0 | | npm run test:functional | Runs public mode, union, and adapter workflows | vanilla-test 2.1.0 | | npm run test:behavioral | Runs observable consumer workflows and side-effect boundaries | vanilla-test 2.1.0 | | npm run test:integration | Runs documentation, package, site, and tooling boundaries | vanilla-test 2.1.0 | | npm run test:regression | Runs corrected edge cases and hostile-value protections | vanilla-test 2.1.0 | | npm run test:legacy | Runs the same registered cases through the compatibility adapter | None | | npm run test:browser | Runs the shared native-browser behavioral inventory in real Chrome | vanilla-test 2.1.0 | | npm run test:conformance | Runs the same bare-import inventory in Node and real Chrome | vanilla-test 2.1.0 | | npm run test:browser-contract | Checks browser metadata, documentation, import maps, and deployment wiring | None | | npm run test:package | Packs and installs the candidate in an isolated ESM consumer | npm | | npm run coverage | Runs the canonical registry through VanillaTest's native Node V8 coverage collector | vanilla-test 2.1.0 | | npm start | Serves the docs and playground at http://localhost:8000/ | None | | npm run nodeExample | Runs the Node example | None |

License

Migration notes · Changelog · MIT · Roshi _ _