Skip to content

Minify JS

The minify_js tool minifies a JavaScript file in place using a pure-stdlib state-machine minifier. No Node.js, no external dependencies, no toolchain rebuild — drop-in minification with full recovery via the standard backup system.

Added in v4.5.7 (2026-06-07). See the CHANGELOG.

For context on the full tool surface, see Core Tools.


Annotations:

AnnotationValue
readOnlyfalse (writes by default; dry_run:true is read-only)
destructivetrue
idempotenttrue (re-running on the already-minified file is a no-op)

Parameters:

ParameterRequiredTypeDefaultDescription
pathYesstringPath to the .js file to minify (overwritten in place)
output_pathNostringIf set, write minified output to this path instead of overwriting path
remove_commentsNobooltrueStrip // and /* */ comments
collapse_whitespaceNobooltrueCollapse runs of spaces/tabs to a single space where needed
single_lineNobooltrueEmit all output on a single line
dry_runNoboolfalsePreview without writing
create_backupNobooltrueCreate a backup before overwriting (only when writing to path)

Errors:

  • If output_path resolves outside --allowed-paths, the call fails with access denied.
  • If output_path would overwrite a symlink pointing outside --allowed-paths, the call fails with the TOCTOU defense message.
  • If all three knobs (remove_comments, collapse_whitespace, single_line) are set to false, the call fails with nothing to do (refuse silently defaulting to a no-op).

The minifier is a best-effort state machine (core/minifier.go). It never modifies the contents of strings, regexes, or template substitutions. It correctly handles:

  • // line comments and /* */ block comments
  • Single- and double-quoted strings (with escapes)
  • Template literals (backticks) including ${expr} interpolation
  • Regex literals (/.../[flags]) with character classes
  • The regex-vs-division disambiguation (real JS tokenizer behaviour)
  • Shebangs (#!/usr/bin/env node at the top of a file)

Conservative heuristics are used for exotic edge cases (regexes with / inside character classes, tagged-template edge cases). When the minifier cannot make a safe decision it leaves the source unchanged — never produces broken output.


minify_js({
path: "app.js",
dry_run: true
})
// → "MINIFY (dry-run) app.js | 87342→31045B (-56297, 64.4%) | comments:42"

Verbose response includes a 500-char preview of the minified output.

minify_js({
path: "app.js"
})
// → "MINIFIED app.js | 87342→31045B (-56297, 64.4%) | comments:42 | UNDO:20260607-xxx"

The original file is moved to the backup directory before the minified copy is written. The backup ID is shown in the response; use it with backup(action:"undo_last", file_path:"app.js") to roll back.

minify_js({
path: "src/app.js",
output_path: "dist/app.min.js",
create_backup: false // source untouched, no backup needed
})
minify_js({
path: "app.js",
remove_comments: false,
collapse_whitespace: false,
single_line: false
})
// → Error: "all of remove_comments, collapse_whitespace, and single_line are false — nothing to do"

Compact:

MINIFY <target> | <in>→<out>B (-<saved>, <pct>%) | comments:<n>[ | UNDO:<id>][ | from:<source>]

Verbose: Source, Output, Input bytes, Output bytes, Saved, Comments stripped, optional preview (first 500 chars), optional truncated:input-malformed warning if the source has an unterminated string or comment.


The minifier creates a backup via the standard BackupManager when overwriting in place. Recovery:

// Undo the most recent minify on this file
backup({action: "undo_last", file_path: "app.js"})
// Preview what would be undone
backup({action: "undo_last", file_path: "app.js", preview: true})
// Restore a specific backup by full ID
backup({
action: "restore",
backup_id: "20260607-xxxxx-full-id",
file_path: "app.js"
})

See Safe editing protocol for the full step-through undo workflow.


Use minify_js when:

  • You need a quick minified copy of a JS file and the user does not want to rebuild via their toolchain (no Node, no webpack, no esbuild).
  • You need to ship a one-off script and want a smaller payload.
  • You want a deterministic, auditable minification that produces a single backup ID you can roll back from.

Do NOT use this tool when:

  • You need advanced transformations (tree-shaking, dead-code elimination, ES-module-to-CJS). The minifier is a pure byte-level minifier — it does not understand module semantics.
  • The source uses exotic syntax the minifier might mishandle. Always dry_run:true first and inspect the preview before live-minifying.

  • Pure stdlib. No external dependencies, no exec.Command calls.
  • State machine. core/minifier.go (~700 LOC) — single pass over the source bytes.
  • Backups. When writing to path and create_backup:true, the backup is created via engine.GetBackupManager() and linked into the file’s PreviousBackupID chain (so undo_last walks it).
  • Cache. engine.InvalidateCache(path) is called after writing, so subsequent read_file calls see the new bytes.

Files: core/minifier.go, tools_minify.go, core/minifier_test.go (25+ cases).



Version: 4.5.29 Last updated: 2026-07-11