# Extension points — webpack/webpack

> Canonical page: https://codevetter.com/unpack/webpack/extension-points

# Extension points — webpack/webpack

Scanned commit 87a62dec2304cd2c163c41feeeb43fbe3e5c21dd (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Extension is the architecture: everything user-visible is a plugin that taps `tapable` hooks, and webpack's own features are implemented the same way user plugins are. The four main seams are (1) the hook objects on `Compiler`, `Compilation` and `NormalModuleFactory`, including `HookMap`s keyed by module type; (2) the `Dependency` + `DependencyTemplate` + `makeSerializable` triple for new dependency kinds; (3) `RuntimeGlobals` + `RuntimeModule` + `runtimeRequirementInTree` for new runtime code; and (4) the plugin-based `RuleSetCompiler` for new `module.rules` vocabulary. Generators of tables and types are themselves extension points — a new CSS math function or HTML attribute is a descriptor added to a `tooling/generate-*-data.js` SUPPLEMENT, not code added to a printer.
- `NormalModuleFactory.hooks` is the richest factory seam: `resolve`, `factorize`, `beforeResolve`, `afterResolve`, `createModule`, `module`, plus five `HookMap`s keyed by scheme or module type (`resolveForScheme`, `resolveInScheme`, `prepareModuleType`, `createParser`/`parser`, `createGenerator`/`generator`, `createModuleClass`), several annotated with `@since` versions. — [lib/module/NormalModuleFactory.js#L628-676](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L628-L676)
- New URL schemes plug in through `resolveForScheme`/`resolveInScheme` — the pattern used by `DataUriPlugin`, `FileUriPlugin`, `HttpUriPlugin` and `VirtualUrlPlugin` in `lib/schemes/`. — [lib/schemes/DataUriPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/schemes/DataUriPlugin.js) [lib/schemes/VirtualUrlPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/schemes/VirtualUrlPlugin.js) [lib/module/NormalModuleFactory.js#L632-642](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L632-L642)
- A new module language is a parser/generator pair registered on the type-keyed HookMaps and cached per options object in `parserCache`/`generatorCache`; `lib/module/Parser.js` and `lib/module/Generator.js` are the base classes, both re-exported publicly as `webpack.Parser` / `webpack.Generator`. — [lib/module/NormalModuleFactory.js#L1946-2040](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L1946-L2040) [lib/module/Parser.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/Parser.js) [lib/module/Generator.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/Generator.js) [lib/index.js#L360-365](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/index.js#L360-L365)
- A new dependency type is the documented triple: a `Dependency` subclass in `lib/dependencies/`, a `DependencyTemplate` registered into `compilation.dependencyTemplates`, and a `makeSerializable(Class, "webpack/lib/…")` call — the pattern appears in 144 files. — [lib/graph/Dependency.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/graph/Dependency.js) [lib/DependencyTemplate.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/DependencyTemplate.js) [lib/util/makeSerializable.js#L60-70](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/util/makeSerializable.js#L60-L70) [AGENTS.md](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/AGENTS.md)
- New runtime code plugs in via `lib/runtime/RuntimeGlobals.js` (97 exported symbols), a `RuntimeModule` subclass, and a tap on `runtimeRequirementInTree`/`additionalTreeRuntimeRequirements`; `RuntimePlugin` is what injects modules for the requirements a build collects. — [lib/runtime/RuntimeGlobals.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/runtime/RuntimeGlobals.js) [lib/runtime/RuntimeModule.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/runtime/RuntimeModule.js) [lib/runtime/RuntimePlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/runtime/RuntimePlugin.js) [lib/Compilation.js#L4484-4530](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compilation.js#L4484-L4530)
- `module.rules` vocabulary is itself pluggable: `RuleSetCompiler` is constructed from rule plugins (`BasicMatcherRulePlugin`, `ObjectMatcherRulePlugin`, `GlobMatcherRulePlugin`, `BasicEffectRulePlugin`, `UseEffectRulePlugin`), so a new condition or effect keyword is a new plugin rather than a branch in the matcher. — [lib/rules/RuleSetCompiler.js#L141-200](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/rules/RuleSetCompiler.js#L141-L200) [lib/rules/GlobMatcherRulePlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/rules/GlobMatcherRulePlugin.js) [lib/rules/UseEffectRulePlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/rules/UseEffectRulePlugin.js)
- Target support is a table-driven registry: adding a target means adding a `[name, description, regExp, handler]` tuple to `TARGETS` in `lib/config/target.js`, and `mergeTargetProperties` plus `UNSUPPORTED_WHEN_ABSENT` decide how multi-target arrays like `["web", "node"]` resolve each capability. — [lib/config/target.js#L128-545](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/config/target.js#L128-L545) [lib/config/target.js#L562-612](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/config/target.js#L562-L612)
- Chunk-loading, wasm-loading and library formats are enabled through dedicated dispatch plugins — `EnableChunkLoadingPlugin`, `EnableWasmLoadingPlugin`, `EnableLibraryPlugin` — which `WebpackOptionsApply` calls per configured type, so a new format registers itself with one of these rather than editing the option branch. — [lib/config/WebpackOptionsApply.js#L355-385](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/config/WebpackOptionsApply.js#L355-L385) [lib/javascript/EnableChunkLoadingPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/javascript/EnableChunkLoadingPlugin.js) [lib/library/EnableLibraryPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/library/EnableLibraryPlugin.js)
- Stats output is extensible through the factory/preset/printer split: `DefaultStatsFactoryPlugin` builds the object graph, `DefaultStatsPresetPlugin` defines named presets, and `DefaultStatsPrinterPlugin` renders it — each a separate tap point. — [lib/stats/DefaultStatsFactoryPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/stats/DefaultStatsFactoryPlugin.js) [lib/stats/DefaultStatsPresetPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/stats/DefaultStatsPresetPlugin.js) [lib/stats/DefaultStatsPrinterPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/stats/DefaultStatsPrinterPlugin.js)
- Module Federation exposes its own hook surface in `lib/container/moduleFederationHooks.js` and `lib/hmr/parserHooks.js` does the same for HMR, so third-party federation/HMR tooling taps a published hook object rather than reaching into the plugin. — [lib/container/moduleFederationHooks.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/container/moduleFederationHooks.js) [lib/hmr/parserHooks.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/hmr/parserHooks.js)
- Caches are pluggable at the `Cache`/`CacheFacade` layer: `MemoryCachePlugin`, `MemoryWithGcCachePlugin`, `IdleFileCachePlugin` and `ResolverCachePlugin` all tap `compiler.cache.hooks.{get,store,storeBuildDependencies}`, so an alternative backing store is a plugin. — [lib/cache/Cache.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/Cache.js) [lib/cache/CacheFacade.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/CacheFacade.js) [lib/cache/IdleFileCachePlugin.js#L60-110](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/IdleFileCachePlugin.js#L60-L110) [lib/cache/ResolverCachePlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/ResolverCachePlugin.js)
- Per-construct minifier behaviour is table-driven by design: the generators own the descriptors (`MATH_FUNCTION_FOLD` in `tooling/generate-css-data.js`, `SUPPLEMENT`/`PARSER_TABLES` in `generate-html-data.js`) and the printers implement only the shared engine keyed by them, so adding a foldable function is adding a generator entry. — [tooling/generate-css-data.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/tooling/generate-css-data.js) [tooling/generate-html-data.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/tooling/generate-html-data.js) [lib/css/data.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/css/data.js) [AGENTS.md](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/AGENTS.md)
- Custom filesystems plug in behind the `InputFileSystem`/`OutputFileSystem` interfaces declared in `lib/fs/fs.js`; `NodeEnvironmentPlugin` supplies the Node-backed defaults and a target may supply its own watcher (`NodeWatchFileSystem`). — [lib/fs/fs.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/fs/fs.js) [lib/node/NodeEnvironmentPlugin.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/node/NodeEnvironmentPlugin.js) [lib/node/NodeWatchFileSystem.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/node/NodeWatchFileSystem.js)
- Schema-driven options are their own extension point: adding a property to `schemas/WebpackOptions.json` regenerates the CLI flag list (`webpack.cli.getArguments`), the precompiled validator, the declaration and the `types.d.ts` member in one `yarn fix:special` run. — [schemas/WebpackOptions.json](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/schemas/WebpackOptions.json) [lib/config/cli.js](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/config/cli.js) [tooling/generate-types.js#L1-40](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/tooling/generate-types.js#L1-L40) [lib/index.js#L14-28](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/index.js#L14-L28)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
