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

webpack-hooks

v1.0.1

Published

Webpack plugin that makes tapping compiler hooks easier

Downloads

3

Readme

Build Status Minimum node.js version downloads version GitLab release MIT License Maintenance


What Are Webpack Hooks?

When Webpack runs, it goes through a sequence of build phases. During each phase, it exposes various hooks that developers can tap into to customize behavior.

You can find a full list of compiler hooks here:
https://webpack.js.org/api/compiler-hooks/

Most compiler hooks (before thisCompilation) provide the compiler object. After that, you typically get the compilation object — which exposes its own powerful hook set:
https://webpack.js.org/api/compilation-hooks/

This allows deep control over both the build life-cycle and the actual compilation pipeline. Webpack-hooks plugin allows you to tap both compiler and compilation hooks.


Installation

npm install --save-dev webpack-hooks

or

yarn add --dev webpack-hooks

Usage

In your Webpack config, import and instantiate the plugin:

const WebpackHooks = require('webpack-hooks');

module.exports = {
  output: {
    path: '/dist',
    publicPath: '/~media/'
  },
  plugins: [
    new WebpackHooks({
      beforeRun: (compiler) => { ... },
      beforeCompile: (params) => { ... },
      compilation: (compilation) => { ... },
      // more hooks here...
    })
  ]
};

Why WebpackHooks?

Webpack's built-in hook API is mostly geared toward writing full plugins. That comes with boilerplate — class structures, life-cycle setup, and file organization (even for tiny customization).

WebpackHooks removes that friction. Just define the hooks you need, right inside your build config.

Without WebpackHooks

class MyWebpackPlugin {
  constructor(options = {}) {
    this.options = {
      ...options
    };
  }

  apply(compiler) {
    compiler.hooks.entryOptions.tap(
      { name: 'MyWebpackPlugin' }, 
      (context, entry) => {
        console.log(context, entry);
      }
    );
  }
}
const MyPlugin = require('./MyPlugin.js');

module.exports = {
  plugins: [ new MyPlugin() ]
};

With WebpackHooks

const WebpackHooks = require('webpack-hooks');

module.exports = {
  plugins: [
    new WebpackHooks({
      entryOption: (context, entry) => {
        console.log(context, entry);
      }
    })
  ]
};

This is ideal for:

  • Small tweaks that don't justify a full plugin
  • Rapid prototyping of custom build logic
  • Zero plugin organization needed

tap vs. tapPromise

Want to use tapPromise instead of tap? Just mark your function async:

new WebpackHooks({
  beforeRun: async (compiler) => {
    await doSomething();
  }
});

Compiler and Compilation hooks

Webpack-hooks plugin indeed supports both Compiler and Compilation hook tapping.

For instance:

new WebpackHooks({
  compilation: {
    statsFactory: {
      result: tapOptions(
        { for: 'compilation' }, 
        (result, context) => {
          ...
        }
      ),          
      extract: tapOptions(
        { for: 'compilation' }, 
        (object, compilation) => {
          ...
        }
      )
    }
  }
})

In the above example we are tapping Compiler.Compilation Compilation.statusFactor and ultimately statusFactory.results and statusFactory.extract hooks.


tapOptions()

Some hooks (like processAssets) require tap options such as stage or additionalAssets.

You can pass these options via tapOptions():

new WebpackHooks({
  compilation: {
    processAssets: tapOptions(
      {
        stage: compilation.PROCESS_ASSETS_STAGE_OPTIMIZE,
        additionalAssets: true
      },
      async (assets) => {
        console.log(assets);
      }
    )
  }
});

💡 Bonus: Using async will automatically use tapPromise.


HookMaps and .for('my-preset')

Some hooks (like compilation's statsPreset or statsFactory's deeper hooks) are what is called a HookMap. This means that in normal plugin syntax, you must chain in a .for('my-preset') into your tapping on hooks that are HookMaps.

In Webpack-hooks plugin, HookMap value is passed in under a tapOptions as a { for: 'my-preset' }:

new WebpackHooks({
  compilation: {
    statsPreset: tapOptions({ for: 'normal' }, (options) => {
      console.log(options);
    })
  }
})

Hook Names

Normally, Webpack requires a name property for each hook tap. With WebpackHooks, it's optional — the fallback is 'WebpackHooks'.

If you want to set a custom name on a hook endpoint:

new WebpackHooks({
  entryOption: tapOptions({ name: 'CustomName' }, (context, entry) => {
    console.log(context, entry);
  })
});

if you want to set a custom global value for all hook names:

new MyWebpackPlugin('MyHookName', {
  entryOption: (context, entry) => {
    console.log(context, entry);
  }
})

if you don't care, and don't mind they will be named 'WebpackHooks':

new MyWebpackPlugin({
  entryOption: (context, entry) => {
    console.log(context, entry);
  }
})

Tests

WebpackHooks comes with a lot of tests. These helps ensure that hooks can be expressed correctly and function as intended.

Simply run npm run test or yarn test from the root of the plugin to run test.

Running a test will produce a /dist/ directory.

If you would like to change a test, update the root package.json file's test script to use any of the /test/*.*.config.js files.