Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package () to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
refine
Remove comments from JavaScript, TypeScript, JSX, TSX, Vue, HTML, CSS/SCSS/LESS and more — with parallel processing, watch mode, .refineignore support and JSON reports.
Installation
Local (per-project)
# bun
bun add -D @nuitsukera/refine
# npm
npm install --save-dev @nuitsukera/refineAfter installing, run the setup wizard once:
# bun
bunx refine init
# npm
npx refine initA refine.json is created in the project root (or merged into your existing config.json if you prefer). A post-install tip is shown automatically if no config is found.
Global
# bun
bun install -g @nuitsukera/refine
# npm
npm install -g @nuitsukera/refineOnce installed globally you can call refine from any directory. A default global config is automatically created on install:
- Linux / Mac:
~/.config/refine/refine.json - Windows:
%APPDATA%\refine\refine.json
Edit that file to customise the default behavior for all projects.
Quick start
# 1. Create config in your project root (interactive)
refine init
# 2. Run (auto-detects refine.json)
refine
# 3. Dry run — preview what would change, no files modified
refine --dry-run
# 4. Watch mode — reprocess on every file change
refine --watchConsole output
Every run prints a per-file report of exactly what was removed and on which line:
refine ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Scanning files...
✓ Found 2 files to process
Processing Files ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Total files to process: 2
src/utils/helper.ts ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ 4 comments removed
1 │ - /** @file helper.ts — utility functions
15 │ - // internal state
42 │ - // TODO: cleanup later
88 │ - /* legacy fallback */
src/components/Button.tsx ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ 2 comments removed
3 │ - // @deprecated
27 │ - /* unused */
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Results ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Files Processed 2 · Files Skipped 0 · Comments Removed 6 · Comments Preserved 0 · Processing Time 12ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Done!In --dry-run mode each file is tagged [dry run] and nothing is written to disk:
src/utils/helper.ts ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ 4 comments removed [dry run]
1 │ - /** @file helper.ts — utility functions
15 │ - // internal stateConfig file auto-detection
When no -c flag is passed, the CLI looks for a config in this order:
refine.jsoninprocess.cwd().refine.jsoninprocess.cwd()refinekey insideconfig.jsoninprocess.cwd()- Global config (
~/.config/refine/refine.jsonon Linux/Mac,%APPDATA%\refine\refine.jsonon Windows)
If none is found, built-in defaults are used and a hint to run refine init is shown.
init command
# Default: creates refine.json in the current directory
refine init
# Custom filename
refine init --output my-config.jsonIf the target config file already exists, refine init exits with a warning:
⚠ Config file already exists: refine.json
Delete it first or use --output to specify a different path.If config.json already exists in the project root and you run init without --output, an interactive prompt asks:
⚠ A config.json already exists in this directory.
How would you like to add refine config?
[1] Merge into existing config.json (adds "refine" key, keeps everything else)
[2] Create a separate refine.json file
[3] Use a custom filename
Choice (1-3):Option 1 — the CLI reads config.json transparently via the "refine" key:
{
"someOtherTool": {},
"refine": {
"targetDirectory": "./src",
"removeJSDoc": false
}
}refine -c config.jsonCLI options
Usage: refine [options] [command]
Options:
-c, --config <path> Path to config file (auto-detected if not specified)
-d, --directory <path> Target directory to process
-o, --output <path> Output directory (overwrites originals if omitted)
-e, --extensions <list> Comma-separated extensions to process (e.g. .js,.ts,.vue)
--concurrency <n> Number of parallel workers (default: 8)
--report <path> Write a JSON report to the specified file
--watch Watch target directory and re-process on changes
--dry-run Run without making changes
-v, --verbose Verbose output (includes per-file line counts)
--remove-jsdoc Remove JSDoc comments
--keep-todo Keep TODO comments
--keep-fixme Keep FIXME comments
--keep-note Keep NOTE comments
-V, --version Output the version number
-h, --help Display help for command
Commands:
init [options] Create the refine config in the current project directory.refineignore
Place a .refineignore file in your target directory to exclude paths using gitignore-style patterns:
# Ignore generated files
dist/
build/
**/*.min.js
# Ignore a specific folder
src/vendor/The file name can be customised via the ignoreFile config field.
Watch mode
refine --watchWatches the target directory recursively. Any change to a matching file triggers a debounced (500 ms) re-run. Press Ctrl+C to stop.
Combine with other flags:
refine --watch --dry-run --verboseJSON report
refine --report report.jsonAfter processing, a report is written to report.json:
{
"timestamp": "2025-01-01T00:00:00.000Z",
"config": { ... },
"stats": {
"filesProcessed": 42,
"filesSkipped": 3,
"commentsRemoved": 187,
"commentsPreserved": 12,
"filesWithErrors": [],
"processingTime": 340
}
}Configuration reference
| Field | Type | Default | Description |
|---|---|---|---|
targetDirectory |
string |
"./src" |
Directory to scan for files |
outputDirectory |
string? |
undefined |
Output directory (overwrites originals if omitted) |
fileExtensions |
string[] |
[".js",".mjs",".cjs",".ts",".jsx",".tsx",".vue",".svelte",".astro",".html",".htm",".jsonc"] |
File extensions to process |
excludeFiles |
string[] |
["*.config.js","*.config.ts"] |
File glob patterns to exclude |
excludeDirs |
string[] |
["node_modules","dist","build",".git"] |
Directories to exclude |
ignoreFile |
string? |
".refineignore" |
Gitignore-style ignore file inside target dir |
preserveComments |
string[] |
["// @ts-expect-error","// @ts-ignore","/// <reference","#!/usr/bin/env node","// biome-ignore","/* webpackIgnore:","/* webpackChunkName:"] |
Exact comment strings to always keep |
preservePatterns |
string[] |
["^\\s*//\\s*@ts-","^\\s*///\\s*<reference","^#!/","biome-ignore","webpack[A-Za-z]"] |
Regex patterns for comments to always keep |
removeJSDoc |
boolean |
false |
Remove JSDoc blocks (/** ... */) |
removeTODO |
boolean |
true |
Remove // TODO: comments |
removeFIXME |
boolean |
true |
Remove // FIXME: comments |
removeNOTE |
boolean |
true |
Remove // NOTE: comments |
dryRun |
boolean |
false |
Preview only, no files written |
verbose |
boolean |
false |
Detailed log output with per-file line counts |
concurrency |
number? |
8 |
Number of parallel worker threads |
reportPath |
string? |
undefined |
Path to write JSON report after processing |
Safety Guard
refine has a built-in Safety Guard layer that runs before any config evaluation. The comments listed below are always preserved, regardless of what refine.json says — no config option can override them.
| Category | What is protected |
|---|---|
| URLs | Any comment containing http:// or https:// |
| Biome | biome-ignore |
| ESLint | eslint-disable, eslint-enable, eslint-env |
| TypeScript | // @ts-*, /// <reference ...> |
| Prettier | prettier-ignore |
| Stylelint | stylelint-disable, stylelint-enable |
| Tailwind | tailwind-ignore |
| Webpack | /* webpackIgnore */, /* webpackChunkName */, etc. |
| Vite / Rollup | vite-ignore, @rollup/ |
| Coverage | istanbul ignore, c8 ignore, v8 ignore |
| Node.js | Shebangs (#!/), "use client", "use server", "use strict" |
| JSX pragmas | @jsx, @jsxRuntime, @jsxImportSource |
| License / Copyright | Any header containing license, copyright, (c) or © |
| Source maps | sourceMappingURL |
| JetBrains IDEs | noinspection |
This means patterns like
.replace(/\//g, "_")(regex literals with/) and CDN URLs inside strings are also protected from being mis-detected as comment content.
Supported file types
| Extension | Parser |
|---|---|
.js .mjs .cjs .ts |
JavaScript / TypeScript |
.jsx .tsx |
JSX / TSX |
.vue |
Vue SFC (template + script + style) |
.svelte .astro |
Vue-style (template + script + style) |
.html .htm |
HTML (<!-- --> + IE conditionals) |
.css |
CSS (/* */) |
.scss .sass .less |
SCSS / SASS / LESS (/* */ + //) |
.jsonc |
JSONC |
Development scripts
| Command | Description |
|---|---|
bun start |
Run CLI from source (src/cli.ts) |
bun run dev |
Run with file watch (auto-restart on change) |
bun run build |
Compile TypeScript → dist/ |
bun run rebuild |
Clean dist/ then compile TypeScript → dist/ |
bun run watch |
Compile TypeScript in watch mode |
bun run prepare |
Rebuild + generate refine.json for development |
bun test |
Run tests |
bun run lint |
Lint src/ with Biome |
bun run format |
Format src/ with Biome |
bun run clean |
Remove the dist/ directory |
How it works (local vs global)
| Install type | How to run | Config location |
|---|---|---|
Local (bun add -D) |
bunx refine / package.json script |
Project root (process.cwd()) |
Global (bun install -g) |
refine from any terminal |
~/.config/refine/refine.json (Linux/Mac) · %APPDATA%\refine\refine.json (Windows) |
Config file paths and all relative paths inside it are resolved against the directory from which refine is called (process.cwd()), never against the package installation directory.
Requirements
License
MIT