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

@nylen/wp-hooks

v1.0.4

Published

WordPress actions and filters in JS

Readme

@nylen/wp-hooks Build Status Coverage

WordPress-style hooks (actions and filters) for Node.js.

Recent (5.x) versions of WordPress also include a JavaScript actions and filters library. It is not exactly the same as this library - this library shares history with the WordPress version, but it is simpler and is mainly intended for usage in Node.js server programs.

When combined with a mechanism for plugin registration and loading (outside the scope of this library), this is a simple, effective pattern that allows modifying values or executing other code at key parts in your app.

More information about actions and filters as they are used in WordPress: https://developer.wordpress.org/plugins/hooks/

Usage

const WPHooks = require( '@nylen/wp-hooks' );
const hooks = new WPHooks();
  • hooks.addAction( 'identifier', callback, priority ) - Add a function to the action given by identifier. Actions do not have return values.
  • hooks.addFilter( 'identifier', callback, priority ) - Add a function to the filter given by identifier. Filters have return values, and functions hooked into a filter can modify its return value.
  • hooks.removeAction( 'identifier', callback ) - Remove an action.
  • hooks.removeFilter( 'identifier', callback ) - Remove a filter.
  • hooks.removeAllActions( 'identifier' ) - Remove all actions from the given identifier.
  • hooks.removeAllFilters( 'identifier' ) - Remove all filters from the given identifier.
  • hooks.doAction( 'identifier', arg1, ... ) - Run an action along with any functions hooked into it.
  • hooks.applyFilters( 'identifier', arg1, ... ) - Run a filter along with any functions hooked into it, and return the default value or the value from the last function.
  • hooks.doingAction( 'identifier' ) - Whether this object is currently executing the action with the name identifier.
  • hooks.doingFilter( 'identifier' ) - Whether this object is currently executing the filter with the name identifier.
  • hooks.didAction( 'identifier' ) - Whether this object has executed the action with the name identifier.
  • hooks.didFilter( 'identifier' ) - Whether this object has executed the filter with the name identifier.
  • hooks.hasAction( 'identifier' ) - Whether this object has any functions hooked into the action with the name identifier.
  • hooks.hasFilter( 'identifier' ) - Whether this object has any functions hooked into the filter with the name identifier.

In large apps, it is a good idea to enforce separation of different types of hooks by either prefixing identifier hook names with namespace.identifier, or (even better) using separate hooks objects for each part of the app.

Sync or Async?

All filters and actions are synchronous by default, and this library contains no special code for async callbacks or promises.

However, because async functions just return Promise objects under the covers, you can easily pass a Promise through a chain of hooks. If you follow a couple of simple rules, then the final result from applyFilters will be a promise that resolves or fails when all of its attached functions have finished processing.

For hooks that may require asynchronous behavior, the app must use a filter rather than an action. Then the app can start the filter chain normally, and just await the final result, which will be a Promise returned from the last function in the filter chain:

const finalValue = await applyFilters(
  'my_async_code_path',
  'defaultValue'
);

Then, individual filters can be written as async functions, as long as they adhere to a simple convention: Accept a Promise as an argument and await it before returning.

addFilter( 'my_async_code_path', async p => {
  const value = await p;
  return value + '/modified';
} );

This allows for any function in the chain of filters to return a Promise, which other functions will wait for before doing their processing. (It's fine to await a non-Promise value too.)

See index.test.js for more examples and information.

Future major versions of this library may change the behavior around asynchronous computations. Currently this mostly works (with the exception of doingFilter and didFilter), but requires adhering to a non-obvious convention and can be difficult to understand and use effectively.