High‑performance HTML formatter for VS Code powered by a Rust binary.
Overview
- Fast parsing with
html5ever
and pretty serialization that respects HTML semantics. - Plug‑and‑play VS Code extension: auto‑discovers or auto‑downloads the right
htmlfmt
binary. - Optional offline installs by bundling platform binaries in the VSIX.
- Drop‑in formatter for VS Code’s “Format Document” (Shift+Alt+F) and Format on Save.
- Status bar shows formatting status and elapsed time.
Table of Contents
- Install
- Usage
- How It Works
- CLI Examples
- Benchmarks
- Troubleshooting
- Security
- Contributing
- License
Install
- VS Code extension
- VSIX (local testing):
npm i -g @vscode/vsce
cd vscode-extension
- Optional: bundle binaries for offline install →
npm run prepare:bins
vsce package
code --install-extension *.vsix
- Marketplace: see “Publish to Marketplace” below.
- Formatter binary (if needed)
- The extension auto‑discovers
htmlfmt
in common locations or auto‑downloads it on first use (configurable). You can also build from source:cargo build --release
- Linux/macOS:
sudo cp target/release/htmlfmt /usr/local/bin/
- Windows:
Copy-Item target\release\htmlfmt.exe "$env:USERPROFILE\\.cargo\\bin\"
Usage
- Open a
.html
file in VS Code - Run “Format Document” (Shift+Alt+F)
- The buffer is piped to
htmlfmt
and replaced with the formatted output. - A popup confirms success with the elapsed time.
How It Works
- Parsing:
html5ever
builds a DOM from input HTML (viakuchiki
). - Pretty serializer: implements
html5ever::serialize::Serializer
to- Preserve text semantics (no changes inside
script
,style
, etc.) - Insert line breaks and indentation between elements while keeping inline text intact
- Handle void elements properly (
br
,img
,meta
, etc.)
- Preserve text semantics (no changes inside
- Streaming: the binary reads stdin and writes formatted HTML to stdout; no filesystem writes.
- VS Code integration:
- Commands: Format Document, Install/Select Binary
- Settings: binaryPath, autoDiscoverWorkspace, enableAutoDownload, statusBar, formatOnSave
CLI Examples
- Unix-like shells (format in place):
htmlfmt < in.html > out.html && mv out.html in.html
- PowerShell:
Get-Content in.html -Raw | htmlfmt | Set-Content in.html -NoNewline
Benchmarks
- Run:
cargo bench
- Uses Criterion with a large synthetic document.
- Public API:
htmlfmt::format_html(&str) -> io::Result<String>
VS Code Extension Settings
rustHtmlFormatter.binaryPath
(string)rustHtmlFormatter.autoDiscoverWorkspace
(boolean)rustHtmlFormatter.enableAutoDownload
(boolean)rustHtmlFormatter.statusBar
(boolean)rustHtmlFormatter.formatOnSave
(boolean)
Troubleshooting
- htmlfmt not found in PATH
- Confirm the binary is installed and the PATH that VS Code uses includes its directory. On macOS, VS Code may not inherit shell PATH; configure your shell integration or launch code from a terminal.
- Permission denied / cannot execute
chmod +x /usr/local/bin/htmlfmt
(Unix). On macOS, allow the binary under System Settings → Privacy & Security if prompted.
- Conflicts with other formatters
- Set the default formatter for HTML to “Rust HTML Formatter” in VS Code settings.
- Unexpected whitespace changes inside <script>/<style>
- The serializer preserves rawtext elements. If you observe issues, open an issue with a minimal repro.
- Large files / memory
- The entire document is held in memory. For very large HTML, ensure sufficient RAM.
- Newline normalization on Windows
- Output uses
\n
. Configure VS Code to normalize line endings on save if CRLF is required.
- Output uses
- Remote / WSL
- Install
htmlfmt
inside the same remote/WSL environment where the workspace is opened.
- Install
Security
- No network calls. Data stays local.
- The extension only launches the local
htmlfmt
process and communicates via stdin/stdout.
Release Process (0.1.5)
- Bump versions (done):
- Crate:
Cargo.toml
→0.1.5
- Extension:
vscode-extension/package.json
→0.1.5
- Changelog:
CHANGELOG.md
updated
- Crate:
- Optional: bundle binaries into VSIX (offline installs)
cd vscode-extension && npm run prepare:bins
- Package the extension
vsce package
- Tag and push to trigger CI release assets
git add -A && git commit -m "chore: release v0.1.5"
git tag -a v0.1.5 -m "v0.1.5"
git push origin main && git push origin v0.1.5
- Verify assets on GitHub Releases and install the VSIX locally.
Publish to Marketplace (VS Code)
- Install tooling:
npm i -g @vscode/vsce
- Create a publisher (one‑time):
vsce create-publisher <your-publisher>
- Update
vscode-extension/package.json
→publisher: "<your-publisher>"
- Login:
vsce login <your-publisher>
(use a Personal Access Token) - From
vscode-extension/
:- If bundling binaries:
npm run prepare:bins
- Publish:
vsce publish 0.1.5
(or justvsce publish
after bumping version)
- If bundling binaries:
- Test from the Marketplace page (verify auto‑download/packaged binaries work offline).
Contributing
- Issues and PRs are welcome. Please include minimal repro HTML when reporting formatting concerns.
License
- MIT License. See
LICENSE
.