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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@wherejuly/null-object

v1.0.2

Published

The tiny polymorphic noop-behavior object to stub actual objects conditionally.

Downloads

70

Readme

Null-Object

A tiny runtime type-safe polymorphic noop object that substitutes for your a real implementation without side effects.

See Null Object pattern [^1].

[^1]: Kerievsky J., Refactoring to Patterns (2004), p. 343; Fowler M., Refactoring (2018), p. 289 under "Introduce Special Case" title.

Package Status

Codecov Quality Gate Technical Debt Code Smells Security Rating

min+gzip

npm bundle size npm bundle size npm downloads License: MIT

Basic Usage

Install the package.

npm install @wherejuly/null-object

Null-Object:

import { nullObject } from '@wherejuly/null-object';

const logger = config.log ? realLogger : nullObject<Logger>();
logger.info('User signed in'); // Always safe to call any method or access property on a null-object

A bundled noop function just for convenience:

import { noop } from '@wherejuly/null-object';

noop(); // returns `undefined`
noop(1, 'a', { b: 'c' }); // as well silently acccepts any arguments

Summary

It is often useful to silently replace an optional dependency, service, or plugin that is not available in some environment (e.g. stub metrics service in development and stage environments).

It is also convenient to use in test to replace dependency objects you do not want to mock but still have to provide into the SUT. Especially, the objects that have the methods to be called by the SUT.

The package provides a safe fallback for any expected object interface by returning a no-op implementation object. It enables cleaner and more robust code due to no null checks or conditional logic.

Any methods called on it are noop, including chained ones. Methods silently accept arbitrary arguments. Access any properties, including nested, silently assign to properties.

Common use cases include:

  • Optional services like logging, analytics, metrics:

    const metrics = prod ? nullObject<Metrics>() : devMetrics;
  • Provide a noop plugin when none is installed:

    const plugin = userProvidedPlugin ?? nullObject<Plugin>();
  • Avoid conditional logic in consumers via default parameter:

    function createHandler(callbacks: Callbacks = nullObject<Callbacks>()) {
     callbacks.onReady(); // Always callable
    }
  • Middleware chains:

    const middleware = [authMiddleware, config.enableAudit ? auditMiddleware : nullObject<Middleware>()];

Usage

The signature:

function nullObject<T = Record<string, any>>(name?: string): T;

Call any method, chained if needed, with arbitrary arguments, access any property, including nested and do nothing. Optionally provide null-object with the actual object type to ensure type safety.

type TSomeActualHandler = { method: any; prop: any }; // May come as third-party type

const silent = nullObject<TSomeActualHandler>();
// Could also use it untyped: `const silent = nullObject()`

silent.method().another('arbitrary', 'args', 123, true);
silent.prop.method('arbitrary', 'args', 123, true).more;

Help debugging with .toString() and optional named identity.

const logger = config.log ? realLogger : nullObject<Logger>();
const name = logger.toString(); // name === [NullObject]
// or
const logger = config.log ? realLogger : nullObject<Logger>('Logger');
const name = logger.toString(); // name === [NullObject: Logger]

Can silently accept assignments to any property including nested.

const plugin = userProvidedPlugin ?? nullObject<Plugin>();
plugin.settings.some = true;

The Convenience noop Function

The package also provides the noop function so that you do not have to import another package for it.

noop(); // returns `undefined`
noop(1, 'a', true, null); // Accepts arbitrary arguments without throwing
function onEvent(callback: () => void = noop) {
 callback(); // Safe to call without checking
}

Maintenance

The package is written in TypeScript with the informative JSDoc blocks available on hover for public interface (e.g. in VS Code) for comfortable programmatic usage. The code is carefully crafted with TDD allowing simple extension. The project is production-ready and actively maintained.

Contributions

Filling issues, questions in Discussions are all welcome.

License

This project is licensed under the MIT License. See the LICENSE file for details.