js-build-utils
v3.0.0
Published
A collection of utility functions for compiling TypeScript, SCSS, minifying JavaScript, CSS, HTML, and more. Designed to be imported by the plugins of other libraries with multiple engines.
Maintainers
Readme
js-build-utils
A collection of utility functions for compiling TypeScript, compiling SCSS, minifying JavaScript, minifying CSS, minifying HTML, and more. It is designed to be imported by the plugins of other libraries, so that a single, uniform API can switch between different engines without changing your code.
Features
- One API, many engines. Every operation exposes a single function, and you pick the underlying engine via an argument. Switch from one engine to another by changing a string.
- Auto / fallback engine selection. Pass
"auto"or an array of engine names to automatically pick the first available engine. - No engines bundled. This package does not ship any compiler, bundler, or minifier. You must install the engine(s) you want to use in your own project; the utilities only
requirethem on demand. - TypeScript-first. Fully typed, ships both ESM and CJS builds (
dist/utils.mjs/dist/utils.cjs) with.d.mts/.d.ctstype declarations.
Installation
# npm
npm install --save-dev js-build-utils
# yarn
yarn add --dev js-build-utils
# pnpm
pnpm add --save-dev js-build-utils
# bun
bun add --dev js-build-utilsThe package itself is engine-agnostic. Install the engine(s) you actually use — see the table in Engines and required dependencies below. If you call a function with an engine that is not installed (or an unknown engine name), it will throw a ReferenceError. If you are using CommonJS but the specific engine is ESM-only, it will throw a TypeError.
Usage
All functions are exported from the package root:
import {
compileTypeScript,
minifyJavaScript,
bundleJavaScript,
compileSass,
compileSassFile,
wrapIife,
createHash,
minifyCSS,
minifyHtml,
minifyJson,
isRolldownVite,
} from "js-build-utils";API
compileTypeScript(source, target?)
Compile TypeScript source code to JavaScript.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| source | string | — | TypeScript source code. |
| target | "ES3" \| "ES5" \| "ES2015" \| "ES2016" \| … \| "ESNext" \| "JSON" \| "Latest" \| "LatestStandard" | "ESNext" | Target JavaScript version. |
import { compileTypeScript } from "js-build-utils";
const js = compileTypeScript("const n: number = 1;");
// const n = 1;Requires typescript.
TypeScript version note. To use
compileTypeScript, make sure your installed TypeScript version is < 7.0 or >= 7.1. Version7.0.xdoes not expose any compiler API that can be used here. If you must stay on7.0.x, install the compatibility package@typescript/typescript6instead; the function falls back to it automatically.
minifyJavaScript(code, engine, type)
Minify JavaScript source code.
| Parameter | Type | Description |
| --- | --- | --- |
| code | string | JavaScript source code. |
| engine | \| "terser" \| "esbuild" \| "oxc" \| "swc"\| "auto"\| ("terser" \| "esbuild" \| "oxc" \| "swc" \| "auto")[] | Engine to use, or "auto" / a fallback array. |
| type | "classic" \| "module" \| "unknown" | Whether the JavaScript code is a classic script or a module. See below. |
type
"classic"— a classic script (not a module). Top-level variables are treated as globals and are not renamed. Must not useimport/export."module"— an ES module. Non-exported variables are renamed to short names.import/exportmay be used."unknown"— unknown. The code is inspected forimport/exportkeywords: if present it is treated as a module, otherwise as a classic script.
import { minifyJavaScript } from "js-build-utils";
const minified = minifyJavaScript("function foo(bar) { return bar; }", "terser", "classic");
// Fall back to the first installed engine.
const minified = minifyJavaScript(code, ["esbuild", "oxc", "terser"], "module");
// Auto-select the best available engine.
const minified = minifyJavaScript(code, "auto", "unknown");| Engine | Package to install |
| --- | --- |
| "terser" | terser |
| "esbuild" | esbuild |
| "oxc" | oxc-minify |
| "swc" | @swc/core |
bundleJavaScript(input, engine, format?)
Bundle an entry file into a single JavaScript module.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| input | string | — | Entry module path. |
| engine | \| "rollup" \| "rolldown" \| "esbuild"\| "auto"\| ("rollup" \| "rolldown" \| "esbuild" \| "auto")[] | — | Engine to use, or "auto" / a fallback array. |
| format | "esm" \| "amd" \| "cjs" \| "iife" \| "system" \| "umd" | "iife" | Output module format. |
Returns a Promise<string>.
import { bundleJavaScript } from "js-build-utils";
const code = await bundleJavaScript("./src/index.ts", "esbuild", "esm");
// Fall back to the first installed engine.
const code = await bundleJavaScript("./src/index.ts", ["rolldown", "esbuild"]);
// Auto-select the best available engine.
const code = await bundleJavaScript("./src/index.ts", "auto");| Engine | Package to install |
| --- | --- |
| "rollup" | rollup |
| "rolldown" | rolldown |
| "esbuild" | esbuild |
compileSass(source)
Compile Sass/SCSS source code to CSS.
| Parameter | Type | Description |
| --- | --- | --- |
| source | string | Sass/SCSS source code. |
import { compileSass } from "js-build-utils";
const css = compileSass(".foo { .bar { color: red; } }");
// .foo .bar { color: red; }Requires sass.
compileSassFile(...filenames)
Compile a Sass/SCSS file to CSS. The arguments are joined with path.resolve, so you can pass path segments individually.
import { compileSassFile } from "js-build-utils";
const css = compileSassFile("src", "styles", "main.scss");Requires sass.
wrapIife(source, options?)
Wrap JavaScript source code in an IIFE (immediately-invoked function expression) or another scoping construct.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| source | string | — | Source code. |
| options | { strict?: boolean; type?: "function" \| "arrow" \| "block" \| "do" \| "do while" } | { strict: true, type: "function" } | Options. type also accepts aliases — see below. |
options.strict
Whether to prepend a "use strict"; directive. Defaults to true.
options.type
The type of IIFE to wrap with. Defaults to "function". Each type has several aliases that behave identically.
| Type | Aliases | Wrapper | Description | Target |
| --- | --- | --- | --- | --- |
| "function" | – | (function () { … })(); | Wraps in a standard immediately-invoked function. Everything defined inside stays out of the global scope. | Any |
| "arrow" | "lambda", "arrow function", "arrow-function" | (() => { … })(); | Wraps in an immediately-invoked arrow function. Same scoping as "function". | ES6+ |
| "block" | "scope", "scoped", "brace", "braces", "block statement", "block-statement" | { … } | Wraps in a bare brace scope. let, const, class, and using declarations do not leak to the global scope; var declarations still do. Whether function declarations leak depends on the strict option: if use strict, they do not leak; otherwise, they leak. | ES6+ |
| "do" | "do expression", "do-expression" | (do { … }); | Wraps in a do expression. Part of a JavaScript proposal that no environment supports yet (2026). | Experimental |
| "do while" | "do-while", "dowhile", "do while false", "do-while-false" | do { … } while (false); | Wraps in a one-time do-while loop. | Any
import { wrapIife } from "js-build-utils";
wrapIife("foo();");
// Result:
(function () {
"use strict";
foo();
})();
wrapIife("foo();", { type: "arrow", strict: false });
// Result:
(() => {
foo();
})();
wrapIife("foo();", { type: "block" });
// Result:
"use strict";
{
foo();
}
wrapIife("foo();", { type: "do" });
// Result:
"use strict";
(do {
foo();
});
wrapIife("foo();", { type: "do while" });
// Result:
"use strict";
do {
foo();
} while (false);createHash(data, algorithm, encoding?)
Create a hash of the given data.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| data | string \| crypto.BinaryLike | — | Data to hash. |
| algorithm | "sha256" \| "md5" | — | Hash algorithm. |
| encoding | crypto.BinaryToTextEncoding | "base64url" | Output encoding. |
import { createHash } from "js-build-utils";
const hash = createHash("hello", "sha256");minifyCSS(source, type?, engine) / minifyCss(...)
Minify CSS source code.
| Parameter | Type | Description |
| --- | --- | --- |
| source | string | CSS source code. |
| type | "inline" \| "media" \| undefined | What part of CSS the source is. See below. |
| engine | \| "lightningcss" \| "esbuild" \| "clean-css" \| "cssnano" \| "csso"\| "auto"\| ("lightningcss" \| "esbuild" \| "clean-css" \| "cssnano" \| "csso" \| "auto")[] | Engine to use, or "auto" / a fallback array. |
type
undefined— a full CSS stylesheet."inline"— an inline style attribute value (e.g. the contents of<div style="…"></div>)."media"— a media query feature string (e.g. the contents of<picture><source media="…" /></picture>).
import { minifyCSS } from "js-build-utils";
minifyCSS(".foo { color: red; }", undefined, "lightningcss");
minifyCSS("display: grid; place-items: center;", "inline", "esbuild");
minifyCSS("screen and (width >= 768px)", "media", "lightningcss");
// Fall back to the first installed engine.
minifyCSS(".foo { color: red; }", undefined, ["lightningcss", "esbuild"]);
// Auto-select the best available engine.
minifyCSS(".foo { color: red; }", undefined, "auto");| Engine | Package to install |
| --- | --- |
| "lightningcss" | lightningcss |
| "esbuild" | esbuild |
| "clean-css" | clean-css |
| "cssnano" | cssnano and postcss |
| "csso" | csso |
- Engine recommendations. While multiple engines are supported,
clean-cssandcssodo not understand newer CSS syntax.clean-cssis in maintenance mode (no longer accepting new features), andcssois effectively unmaintained.cssnanohandles newer syntax but is very slow. Prefer the modernesbuildorlightningcssengines.cssnanorequirespostcss.cssnanois only a PostCSS plugin, so you must also installpostcssto use it.- New CSS
if()syntax. As of 2026, none of the commonly used engines can correctly minify the new CSSif()expression syntax.
minifyHtml(source, engine) / minifyHTML(...)
Minify HTML source code.
| Parameter | Type | Description |
| --- | --- | --- |
| source | string | HTML source code. |
| engine | See below | Engines to use, or "auto". |
The engine argument is either the string "auto" or an object { html, js, css }:
html— the HTML minifier: a single engine name, a fallback array, or"auto".js— the JavaScript minifier: a single engine name, a fallback array,"auto", orfalseto skip JavaScript minification.css— the CSS minifier: a single engine name, a fallback array,"auto", orfalseto skip CSS minification.
import { minifyHtml } from "js-build-utils";
await minifyHtml(html, { html: "terser", js: "terser", css: "clean-css" });
await minifyHtml(html, { html: "next", js: "oxc", css: "lightningcss" });
await minifyHtml(html, { html: "swc", js: "swc", css: "lightningcss" });
// Skip JS/CSS minification
await minifyHtml(html, { html: "swc", js: false, css: false });
// Auto everything
await minifyHtml(html, "auto");
// Fallback + Auto + Auto
await minifyHtml(html, { html: ["terser", "next"], js: "auto", css: "auto" });
// Auto + Fallback + Specific
await minifyHtml(html, { html: "auto", js: ["oxc", "esbuild"], css: "esbuild" });Returns a Promise<string>.
| HTML engine | Package to install | JS engine(s) | CSS engine(s) |
| --- | --- | --- | --- |
| "terser" | html-minifier-terser | "terser", "esbuild", "oxc", "swc"(or "auto" / array) | "lightningcss", "esbuild", "clean-css", "cssnano", "csso"(or "auto" / array) |
| "next" | html-minifier-next | "terser", "esbuild", "oxc", "swc"(or "auto" / array) | "lightningcss", "esbuild", "clean-css", "cssnano", "csso"(or "auto" / array) |
| "swc" | @swc/html | "swc" only | "swc" or "lightningcss" |
Default sub-engine mapping:
- When
htmlis"terser"(html-minifier-terser), the default JS minifier isterserand the default CSS minifier isclean-css. - When
htmlis"next"(html-minifier-next), the default JS minifier isterserand the default CSS minifier islightningcss.- NOTE:
html-minifier-nextis an ESM-only package, you cannot use it in a CommonJS module or project.
- NOTE:
- When
htmlis"swc"(@swc/html), the JS and CSS minifiers cannot be fully customized: the JS minifier can only beswc, and the CSS minifier is eitherswcorlightningcss.
IMPORTANT: You can also pass false to js or css property to skip that minifier entirely.
When the whole engine is "auto", the HTML engine is chosen in the order terser → next → swc; if it resolves to swc, both JS and CSS default to swc, otherwise they default to "auto".
Since HTML minifiers do not expose whether a <script> tag is type="module", the internal minifyJavaScript call always passes "unknown" as the type.
Install the packages for whatever js / css engines you select as well — they follow the same dependency lists as minifyJavaScript and minifyCSS.
minifyJson(source) / minifyJSON(...)
Minify JSON source code.
| Parameter | Type | Description |
| --- | --- | --- |
| source | string | JSON source code. |
It first tries to parse the source as standard JSON; if that fails, it parses it as a JavaScript object literal; if that also fails, it strips newlines and indentation as a last resort.
import { minifyJson } from "js-build-utils";
minifyJson('{\n "foo": "bar"\n}'); // {"foo":"bar"}
minifyJson('{ foo: "bar", }'); // {"foo":"bar"} (JavaScript object literal)No engine or dependency is required.
isRolldownVite()
Check whether the current Vite is a Rolldown-based Vite (Vite 8.0+).
import { isRolldownVite } from "js-build-utils";
if (isRolldownVite()) {
// Vite is built on Rolldown.
} else {
// Vite is built on Rollup.
}Requires vite.
Engines and required dependencies
This package does not bundle any engine. Install only the ones you use:
| Operation | Engine | Dependency | Module Format |
| --- | --- | --- | --- |
| Compile TypeScript | tsc | typescript (or @typescript/typescript6 on TypeScript 7.0.x) | ESM + CJS |
| Compile Sass/SCSS | sass | sass | ESM + CJS |
| Minify JavaScript | terser | terser | ESM + CJS |
| Minify JavaScript | esbuild | esbuild | ESM + CJS |
| Minify JavaScript | oxc | oxc-minify | ESM + CJS |
| Minify JavaScript | swc | @swc/core | ESM + CJS |
| Bundle JavaScript | rollup | rollup | ESM + CJS |
| Bundle JavaScript | rolldown | rolldown | ESM + CJS |
| Bundle JavaScript | esbuild | esbuild | ESM + CJS |
| Minify CSS | lightningcss | lightningcss | ESM + CJS |
| Minify CSS | esbuild | esbuild | ESM + CJS |
| Minify CSS | clean-css | clean-css | CJS Only |
| Minify CSS | cssnano | cssnano + postcss | CJS Only |
| Minify CSS | csso | csso | ESM + CJS |
| Minify HTML | terser | html-minifier-terser (+ chosen JS/CSS minifiers) | ESM + CJS |
| Minify HTML | next | html-minifier-next (+ chosen JS/CSS minifiers) | ESM Only |
| Minify HTML | swc | @swc/html (+ @swc/core, and lightningcss if used) | ESM + CJS |
| Minify JSON | — | (None) | — |
| Check Rolldown Vite | vite | vite | ESM + CJS |
- If a required dependency is missing — or if you pass an unknown engine name — the function throws a
ReferenceError. - If you are using CommonJS but the required dependency is ESM-only — the function throws a
TypeError. - If you are using ESModule but the required dependency is CJS-only — it will work fine, do not care about it.
- Passing
"auto"or an array tominifyJavaScript,bundleJavaScript,minifyCSS, orminifyHtmluses the fallback order described in Engine selection.
Engine selection: "auto" and fallback arrays
For the engine argument of minifyJavaScript, bundleJavaScript, minifyCSS, and minifyHtml, in addition to a single engine name you can pass:
- An array of engine names — The function tries each engine in the order given and uses the first one that is installed. If none of them are installed, it throws a
ReferenceError. - The string
"auto"— Equivalent to passing a preset array (see the table below). The preset order is derived from weighted scoring of unit-test runtime, minification quality, and community adoption rate. "auto"may also appear inside an array, where it behaves like JavaScript's spread operator: the default fallback order is expanded into that position, and the result is deduplicated so the first occurrence of an engine wins. Only the first"auto"is expanded — any later"auto"is ignored.- For example,
minifyJavaScript(code, ["esbuild", "auto"], "unknown")expands toesbuild→oxc→swc→terser:- The default order
oxc→swc→esbuild→terseris inserted afteresbuild, then the duplicateesbuildis removed.
- The default order
- For example,
| Function | "auto" fallback order |
| --- | --- |
| minifyJavaScript | oxc → swc → esbuild → terser |
| bundleJavaScript | rolldown → esbuild → rollup |
| minifyCSS | lightningcss → esbuild → cssnano → clean-css → csso |
| minifyHtml | terser → next → swc (HTML engine) |
Alias for functions
Some functions have alias names that behave identically:
| Function | Alias |
| --- | --- |
| minifyCSS | minifyCss |
| minifyHtml | minifyHTML |
| minifyJson | minifyJSON |
In the source code the aliases are marked @deprecated, but they are never actually deprecated and will keep working. This is only a cosmetic trick: otherwise both the original and the differently-cased alias (e.g. minifyCSS and minifyCss) would appear side by side in your editor's code-completion list and look like they might do different things. Marking the alias @deprecated grays it out in that list, so you can ignore it. If the canonical casing does not match your preference, you are free to use whichever alias suits you.
