babel-loader
Babel loader for webpack (and Rspack) that transpiles modern JavaScript with filesystem caching and source map support.
Repository Health
Technical Analysis
babel-loader integrates Babel into webpack (and Rspack) build pipelines, transforming ES6+ and JSX/TypeScript-via-preset source files into browser-compatible JavaScript as part of the bundling process. It merges loader options with a project’s existing Babel configuration (babel.config.js/.babelrc), exposes webpack’s build target to Babel plugins via the caller API, and registers a source file’s Babel config files as webpack dependencies so config changes trigger rebuilds.
Beyond basic integration, it ships a filesystem cache that hashes source, options, and external-dependency timestamps to skip re-transforming unchanged files across builds, a .custom() loader-builder API for wrapping and intercepting babel-loader’s own options/config/result pipeline, and Node/Babel version gating that fails fast with actionable errors when incompatible packages are installed.
What You Get
- Webpack & Rspack loader integration - drop babel-loader into a
module.rulesentry and it hands transformed code and source maps straight back to the bundler. - Filesystem transform caching - hashes source, Babel options, and a cache identifier per file, storing gzip-compressed results in
node_modules/.cache/babel-loader(or a custom directory) to skip redundant recompiles. - External dependency invalidation - tracks files referenced during a Babel transform (e.g. by plugins that read other files) and busts the cache when their timestamps change.
- Customizable loader via
.custom()- wrap babel-loader’scustomOptions/config/resulthooks to intercept and modify options, Babel’s resolved config, or the transform result before it reaches webpack. - Webpack target awareness - injects webpack’s
target(e.g.web,node) into Babel’scallerAPI so presets/plugins like@babel/preset-envcan branch behavior per bundle target.
Common Use Cases
- Transpiling modern JS for browser bundles - a webpack config adds babel-loader with
@babel/preset-envto compile ES2020+ syntax down to a browserslist-defined target set. - Speeding up repeat builds in CI/dev - a team enables
cacheDirectory: trueso unchanged files skip Babel entirely on subsequentwebpack --watchruns. - Sharing one Babel config across multiple bundlers - a monorepo keeps a single
babel.config.jsthat both babel-loader (webpack) and a separate@babel/clibuild step consume identically. - Building target-specific bundles - a library ships separate Node and browser bundles from one webpack config, using
caller.targetinbabel.config.jsto swap@babel/preset-envtargets per build. - Wrapping babel-loader for a shared internal toolchain - a platform team publishes a
.custom()-based wrapper loader that injects an internal plugin into every consuming project’s Babel config without changing theirbabel.config.js.
Under The Hood
Architecture
babel-loader is a small, cleanly separated pipeline: src/index.js is the webpack loader entry point that normalizes loader options, calls babel.loadPartialConfigAsync, and then delegates to cache.js (filesystem cache layer) or transform.js (direct Babel invocation) depending on the cacheDirectory option, with injectCaller.js injecting webpack target info into Babel’s caller API, serialize.js providing a custom stable serializer for cache-key hashing, and Error.js wrapping Babel’s SyntaxError/TypeError into a cleaner BabelLoaderError. The design is a straightforward layered flow (loader entry to config resolution to cache-or-direct-transform to result post-processing) with minimal shared state and clear single-responsibility files; changing the core transform abstraction would ripple into both the cache layer and the loader entry point since both call it directly and depend on its normalized result shape.
Tech Stack
The codebase is plain CommonJS with // @ts-check type-checking against a tsconfig.json (noEmit, allowJs) rather than actual TypeScript source. It carries a single runtime dependency (empathic, for upward file lookup) plus peer dependencies on @babel/core, an optional @rspack/core, and an optional webpack. The build step compiles src/ to lib/ via Babel itself, tests run on Node’s built-in test runner with c8 for coverage, linting uses ESLint’s flat config with @babel/eslint-parser and eslint-config-prettier, and the package is managed with Yarn 4 (Berry) plus Husky/lint-staged pre-commit hooks, with CI defined in .github/workflows/ci.yml.
Code Quality
A substantial test suite covers the cache layer, the loader itself, metadata subscribers, options handling, the serializer, and source maps, run via Node’s native test runner with coverage and gated in CI alongside a tsc type-check and ESLint pass (preversion runs tsc and the full test suite before every release). Error handling is deliberate: a custom LoaderError distinguishes SyntaxError/TypeError from other failures and explicit try/catch fallbacks in the cache layer degrade gracefully when a target directory isn’t writable. Naming is consistent camelCase throughout, and JSDoc typedefs give the whole codebase real type coverage without a full TypeScript migration.
What Makes It Unique
Rather than a generic caching layer, babel-loader implements a custom Babel-options serializer that intentionally deviates from JSON.stringify for faster, more stable cache-key hashing of complex option objects, plus an external-dependency timestamp-tracking scheme so cache entries correctly invalidate when a file referenced by a plugin (not just the main module) changes. Its .custom() wrapper API is also a specific, narrow solution to a real problem: it lets third-party wrapper loaders intercept options, config, and results while guaranteeing they share the exact same @babel/core instance as babel-loader itself, avoiding duplicate-Babel-version bugs.
Used by 51 apps in this directory
Notesnook
File Storage · Note Taking · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Omnivore
Bookmarks Archiving · Knowledge Management · Note Taking
Self-hosted read-it-later platform with highlights, newsletters, PDFs, and seamless Obsidian and Logseq integration.
open-code-review
Developer Tools · Devops
The AI code review agent born at Alibaba's scale — combining deterministic engineering with LLM intelligence for precise, token-efficient reviews.
opencloud
File Storage
Open source file management and collaboration platform that keeps your data under your control, no database required.
OpenSign
Digital Signiture
Self-host a full-featured DocuSign alternative with unlimited e-signatures, multi-signer workflows, and cryptographic PDF signing.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
Portainer
Devops
A lightweight, open-source web UI that puts Docker, Kubernetes, and Podman management within reach of any team—no CLI expertise required.
Puter
Developer Tools · File Storage
A self-hostable, web-based internet OS with desktop GUI, cloud storage, AI drivers, and a developer SDK — all running in your browser.
React Cosmos
Developer Tools
An open-source sandbox for developing and testing React and React Native UI components in isolation, with pluggable bundler support for Vite and Webpack.