@nuitsukera/refine
v1.0.3
Published
Remove comments from JavaScript/TypeScript, CSS/SCSS/LESS, HTML, Vue and related files
Maintainers
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
