hihtml—“high-quality HTML”—bundles several key HTML tools into one, making HTML validation and semantics control, link checking, and minification as easy as it gets: HTML-validate for validation, ObsoHTML for deprecated markup detection, Node’s built-in http/https for link checking, and HTML Minifier Next for minification. hihtml provides a CLI and a programmatic API, and comes with strong defaults but is still highly configurable.
npm i hihtmlTip: If you don’t plan to use hihtml programmatically, just run hihtml via npx hihtml!
Without options, hihtml validates HTML files and checks for deprecated markup in the current directory. Use flags to control behavior:
| Flag | Description |
|---|---|
-c, --check-code |
Check HTML code: validate and check for deprecated markup (default) |
-l, --check-links |
Check all external http/https URLs for broken references |
-m, --minify |
Minify HTML files in-place, or to --output |
-a, --all |
Check HTML code and links, then minify if there are no validation errors (built-in conformance gate—different from using all individual flags together) |
-i, --input <dir> |
Input directory (default: current directory) |
-o, --output <dir> |
Output directory for minification |
-s, --settings <file> |
Load configuration from a specific JSON file (overrides CWD config lookup) |
-q, --quiet |
Suppress output when no issues are found |
-r, --report [file] |
Save a JSON report (default: hihtml-report.json) |
-v, --version |
Show version number |
-h, --help |
Show help |
Check the current directory:
npx hihtmlCheck a specific folder:
npx hihtml -c -i path/to/projectCheck all external http/https URLs in the current directory:
npx hihtml -lCheck markup and links together:
npx hihtml -c -lMinify HTML files in-place (prompts for confirmation):
npx hihtml -mMinify into a separate output directory:
npx hihtml -m -i src -o distCheck, then minify only if validation passes:
npx hihtml -aUse a specific settings file:
npx hihtml -s ~/my-hihtml.json
npx hihtml -a -i /path/to/site -s ~/my-hihtml.jsonSave a JSON report:
npx hihtml -r
npx hihtml -r results.jsonRun quietly (no output when clean, useful in CI):
npx hihtml -q
npx hihtml -q -l
npx hihtml -q -a -i src -o distimport { checkCode, checkCodeString, checkLinks, checkLinksString, minify, minifyString, collect } from 'hihtml';
const files = await collect('./src');
const checks = await checkCode(files);
// { validation: { files, countErrors, countWarnings, countIgnored }, deprecation: { files, countIssues } }
const links = await checkLinks(files);
// { files: [{ path, links: [{ url, status, ok, skipped?, warning?, error? }], countBroken }], countBroken, countChecked, countSkipped, countFileErrors }
const minification = await minify(files, files); // in-place
// { files: [{ path, sizeOriginal, sizeMinified }], saved }
// String variants—same result types, no file I/O
const minified = await minifyString('<p>Hello world</p>');
const codeGate = await checkCodeString('<p><div>Nope</div></p>');
const linksCleaned = await checkLinksString('<a href=https://example.com/>Example</a>');Recursively collects HTML files from dir. Returns Promise<string[]>.
extensions:Set<string>of file extensions without dots (default:html,htm,shtml,shtm)excludedDirs:Set<string>of directory names to skip (default:node_modules,.git)
Symlinked files whose target resolves within the scanned root are followed; symlinks pointing outside the root or to directories are skipped.
Validates HTML files and checks for deprecated markup. Returns Promise<ResultCode> with validation (HTML-validate result) and deprecation (ObsoHTML result) properties.
options.preset: HTML-validate preset name (default:'standard')options.ignore: List of HTML-validate rule IDs to suppress (default:[])
Validates an HTML string and checks for deprecated markup. Returns Promise<ResultCode>—same shape as checkCode. Useful in content-pipeline contexts (Eleventy transforms, middleware, SSR) where HTML is available as a string rather than a file.
options.preset: HTML-validate preset name (default:'standard')options.ignore: List of HTML-validate rule IDs to suppress (default:[])
Note: result.validation.files[0].path and result.deprecation.files[0].path will be '(string input)', not a real file path.
Checks all external http/https URLs (href, src, srcset, action attributes) found in the given HTML files. Each unique URL is checked once; results are mapped back to every file it appears in. Returns Promise<ResultLinks>.
options.timeout: Request timeout in milliseconds (default:10000)options.concurrency: Maximum concurrent requests (default:8)options.warnOnPermanentRedirects: Warn on 301/308 permanent redirects (default:false)options.ignore: List of hostnames or URL prefixes to skip (default:[])options.onStart: Called once with the total number of URLs to checkoptions.onProgress: Called after each URL is checked
Links are checked via HEAD request, falling back to GET on 405. 4xx and 5xx responses are reported as broken. Skipped URLs (from the ignore list) appear in results with skipped: true and are never counted as broken.
Checks all external http/https URLs found in an HTML string. Returns Promise<ResultLinks>—same shape as checkLinks. Useful when HTML is available as a string rather than a file, e.g., to check links in a fetched document or API response.
options.timeout: Request timeout in milliseconds (default:10000)options.concurrency: Maximum concurrent requests (default:8)options.warnOnPermanentRedirects: Warn on 301/308 permanent redirects (default:false)options.ignore: List of hostnames or URL prefixes to skip (default:[])options.onStart: Called once with the total number of URLs to checkoptions.onProgress: Called after each URL is checked
Note: result.files[0].path will be '(string input)', not a real file path. result.countFileErrors will always be 0.
Minifies HTML files using HTML Minifier Next. Returns Promise<ResultMinification>.
outputPaths: Parallel array of output paths; pass the same value asfilePathsfor in-place minificationoptions.preset: HTML Minifier Next preset name (default:'comprehensive')options.options: Additional HTML Minifier Next options to merge with the preset
Minifies an HTML string using HTML Minifier Next. Returns Promise<string>. Useful in content-pipeline contexts (Eleventy transforms, middleware, SSR) where HTML is available as a string rather than a file.
options.preset: HTML Minifier Next preset name (default:'comprehensive')options.options: Additional HTML Minifier Next options to merge with the preset
Loads hihtml configuration. When filePath is given, only that file is read (no CWD fallback); if it contains a "hihtml" key that value is used, otherwise the root object is used. Without filePath, reads .hihtml.json or the "hihtml" key in package.json from cwd. Returns Promise<HihtmlConfig>.
Create a .hihtml.json file in your project root, or add a "hihtml" key to package.json. Both use the same format (here showing hihtml’s defaults):
{
"extensions": ["html", "htm", "shtml", "shtm"],
"ignore": ["node_modules", ".git"],
"validation": {
"preset": "standard",
"ignore": []
},
"links": {
"timeout": 10000,
"concurrency": 8,
"warnOnPermanentRedirects": false,
"ignore": []
},
"minification": {
"preset": "comprehensive"
}
}.hihtml.json takes precedence over package.json when both are present.
| Code | Meaning |
|---|---|
0 |
No issues found (ObsoHTML warnings on deprecated markup are informational) |
1 |
Validation errors, broken links, or minification errors found |
2 |
Tool or runtime error |
Use the individual flags (-c, -l, -m) instead of --all/-a. Each flag only exits “1” for issues within its own scope, so you control exactly what affects the exit code. To suppress specific HTML-validate rule IDs without disabling validation entirely, use validation.ignore in your configuration. To suppress specific broken links without skipping link checking altogether, use links.ignore.
If in doubt or in a hurry, report issues here. Otherwise, if the issue is related to HTML-validate, report it with HTML-validate. If the issue is related to ObsoHTML, report it with ObsoHTML. For HTML Minifier Next issues, report them with HMN. All projects are monitored and should respond promptly. Thank you!
At the moment, ObsoHTML catches some elements and attributes that HTML-validate doesn’t. Once HTML-validate covers everything ObsoHTML covers, ObsoHTML is going to be removed from hihtml. Note that ObsoHTML is purely informational—it doesn’t prevent minification when used with the --all/-a flag.
You might like some of my other work:
- Optimization tools: hihtml (including HTML Minifier Next + ObsoHTML) · Image Guard · Compressor.js Next · .htaccess Punk
- Defense tools: IA Defensa
- Resources for quality web development: Articles · Books (including On Web Development) · News · Terminology