replace-ext
A tiny, dependency-free Node.js utility that replaces a file path's extension with another one.
Repository Health
Technical Analysis
replace-ext is a minimal Node.js utility from the gulp team that swaps the extension of a file path for a different one. Given a path and a new extension, it returns the same path with the old extension removed and the new one appended, correctly handling the directory, basename, and edge cases like empty strings or non-string inputs.
Despite its tiny footprint, it carefully preserves a leading ./ segment that Node’s built-in path.join would otherwise strip, which matters when the result is passed to require or import. It ships with no runtime dependencies and is downloaded millions of times per week, largely as an internal building block of the gulp ecosystem.
What You Get
- A single
replaceExt(path, ext)function that swaps a file path’s extension - Correct preservation of a leading
./thatpath.joinwould normally remove - Safe handling of empty strings and non-string inputs, which are returned unchanged
- Zero runtime dependencies and a tiny install footprint
Common Use Cases
- Rewriting output filenames in a build or bundler pipeline (e.g.
.tsto.js) - Changing extensions on Vinyl file objects inside gulp plugins
- Deriving a companion file path such as a
.mapor.d.tsfrom a source path
Under The Hood
Architecture - The entire library is a single index.js exporting one replaceExt(npath, ext) function. It guards against non-string and empty inputs by returning them unchanged, then rebuilds the path with path.basename(npath, path.extname(npath)) + ext joined onto path.dirname(npath). A small startsWithSingleDot helper detects a leading ./ (or .\ on Windows) and re-prepends it, because path.join strips that segment and its loss would break downstream require/import calls.
Tech Stack - Plain CommonJS JavaScript targeting Node.js, with no runtime dependencies beyond Node’s built-in path module. Development tooling is limited to a linter and a test runner wired through the lint, pretest, and test scripts.
Code Quality - The implementation is small, readable, and defensively written, with an inline comment explaining the non-obvious dot-slash handling. The repository includes a dedicated test directory, and the package’s place at the base of the widely used gulp toolchain means its behavior is heavily exercised in practice.
API Design - The API is about as simple as it gets: one function, two arguments, a string return value, and no options or configuration. Its behavior is predictable and its name is self-explanatory, so there is essentially no learning curve for adopting it.