Web Tools
Web Tools is an anonymously accessible, self-hosted collection of browser-local utilities built with Vue 3, TypeScript, Vite, and a small zero-dependency Node.js server. It supports multiple simultaneous users: text, keys, files, images, and calculation results remain inside each browser tab. The server only persists the navigation order shared by all visitors.
The authoritative application version is the version field in package.json. The default production address is http://localhost:9000.
Included tools
- UTF-8 and Hex conversion at the canonical route
/tools/utf8-hex - Base64 and Base64 URL encoding/decoding, with UTF-8, continuous Hex, and source-code byte-array output
- AES-CMAC with selectable AES-128, AES-192, and AES-256 keys
- 16 reviewed CRC-8/16/32/64 presets and custom parameters for inline Hex bytes, BIN, and multi-block Intel HEX files
- Firmware SHA-256/SHA-512 over Intel HEX effective data, optionally with an address/length header for each block
- RSA 2048/3072/4096-bit key-pair generation with PEM, N/E Hex, and byte-array output
- RSA PKCS#1 v1.5 and RSA-PSS signature verification (RSA-PSS by default) with SHA-256/384/512, PEM/X.509/N-E public keys, and text, Hex, raw-file, Intel HEX effective-data, or Intel HEX block-header input
- Cryptographically secure random bytes in continuous Hex, spaced Hex, or byte-array form, defaulting to 16 bytes
- JSON formatting, minification, validation, and syntax highlighting
- XML formatting, minification, validation, and syntax highlighting
- PNG to multi-size ICO conversion
Security and state model
- Tool data is processed locally in browser memory and is not sent to the server or a third party.
- There is no login, account, favorites, sponsorship, telemetry, application-loaded CDN asset, or database.
- The Node server emits a fresh 128-bit CSP nonce on every response. Cloudflare can attach it to JavaScript Detections injected by its proxy without enabling
unsafe-inline; this compatibility does not add application analytics or send tool inputs away from the browser. /tools/settingis the fixed, deliberately unlisted management route. It is not authentication: anyone who can reach the application can open that URL and change the globally shared navigation order.- Existing navigation files that still contain the legacy
ascii-hextool ID are migrated in place toutf8-hex, preserving their category and position. New configurations and application routes use onlyutf8-hex. - The first-run default category order is Encoding, Checksum, Cryptography, Formatting, and Image. A saved
navigation.jsonintentionally keeps its existing custom order; it is not silently reset by an application update. - Theme selection is stored in same-origin browser
localStorage. The only server-side application data isnavigation.json. - CRC and Firmware Hash share the same file picker and loaded-file summary. After a file is loaded, a replacement can be dropped directly onto that summary. The candidate is parsed in a separate Worker and replaces the active file only after successful validation; an invalid replacement preserves the current file and results.
- CRC presets are grouped by width and use canonical names. They cover CRC-8/SMBUS, MAXIM-DOW, and SAE-J1850; CRC-16/ARC, DNP, IBM-3740, IBM-SDLC, KERMIT, MODBUS, USB, and XMODEM; CRC-32/ISO-HDLC, ISCSI, and MPEG-2; and CRC-64/ECMA-182 and XZ. Familiar aliases such as CRC-8, CCITT-FALSE, CCITT, X-25, and CRC-32C remain visible to disambiguate otherwise overloaded names.
- RSA signature verification is verification-only and never requests a private key. X.509 input only extracts the RSA public key and displays certificate metadata; it does not validate trust, issuer, usage, validity, or a certificate chain. Raw-file, Intel HEX effective-data, and Intel HEX block-header modes are explicit and never inferred from the filename. Block-header mode uses the same binary per-block
startAddress/dataLengthcontract and byte-order selection as Firmware Hash. - In N/E input mode, E is an unsigned Hex integer. Odd-length input is left-padded by one zero nibble, so
10001and010001both represent decimal 65537; Hex byte inputs elsewhere remain even-length. - Browser navigation writes carrying Fetch Metadata are accepted only when
Sec-Fetch-Siteissame-origin. Clients that omit the header are still accepted, so this is defense in depth rather than authentication. - The application is suitable for a private network, VPN, or a deployment protected by an external access-control layer. Do not treat the hidden settings URL as an Internet-facing security boundary.
See README.zh-CN.md for the exact algorithm contracts, input limits, concurrency behavior, and server security controls.
Resource limits
The browser rejects oversized or structurally dense inputs before costly allocation. The current limits are 64 MiB for firmware/signature files and merged Intel HEX effective data, 1 MiB each for parsed inline CRC Hex and inline signature-verification data with a 6 MiB input-character guard, 1,024-8,192 bits for verification RSA moduli, 500,000 non-empty Intel HEX records, 1,024 Intel HEX blocks, 32 MiB for compressed PNG files, 16,384 pixels per PNG side and 32,000,000 decoded pixels, 1-65,536 bytes for secure random output (default 16), and 100,000 characters/10,000 tokens for syntax highlighting. Highlighting falls back to complete plain text; it never truncates a result.
Docker deployment
Requirements: Docker Engine 24+ and Docker Compose v2 on Linux AMD64 or ARM64.
docker compose up -d --build
Open http://server-address:9000. To change the host port, copy .env.example to .env, set WEB_TOOLS_PORT, and start Compose normally. The container always listens on port 9000 internally.
Useful commands:
docker compose ps
docker compose logs --tail=100 web-tools
docker compose down
Navigation settings are stored in the named volume web-tools-data. Recreating the container does not remove them; docker compose down -v does.
Windows Server deployment
Requirements: Git, Node.js 22.12.0 or newer, and PowerShell 5.1 or newer. After cloning the repository:
Set-Location C:\Services\WebTools
npm.cmd ci --include=dev
npm.cmd run build
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 start
The script listens on 0.0.0.0:9000 by default and stores navigation settings in C:\ProgramData\WebTools\data\navigation.json. It accepts -ListenAddress, -Port, and -DataDir overrides. It does not create Windows Firewall rules.
Running web-tools.ps1 without an action opens an interactive menu: start the existing build, update/rebuild/start, update/rebuild without starting, or exit. Explicit start and update arguments remain available for shortcuts, scheduled tasks, and automation. When launching interactively after a repository update, choose option 2; option 1 intentionally starts the existing dist without rebuilding it.
To update a clean checkout on the main branch, stop the foreground process with Ctrl+C, then run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 update
The update action performs a fast-forward-only pull, rebuilds dependencies from package-lock.json, creates a production build, and starts the server. Use -NoStart when a scheduled task or service manager will restart it separately.
A Windows single-EXE build is not currently shipped. The Node.js plus PowerShell path and Docker are the supported deployment methods. The Chinese documentation describes the design and cost of adding an optional Node.js Single Executable Application release later.
Local development
Install dependencies with npm ci. Development uses two terminals because Vite proxies configuration requests to a separate local Node server. Port 8081 is only this development proxy target, not a production port.
Terminal one on PowerShell:
$env:PORT = '8081'
$env:DATA_DIR = (Join-Path (Get-Location) 'data')
node .\server\index.mjs
Terminal two:
npm run dev
Full validation:
npm run check
npm audit --audit-level=low
npm run check runs the Vitest suite, Vue/TypeScript type checking, and a production build.
Architecture and extension points
src/components/ shared UI components
src/composables/ reusable Vue state and asynchronous lifecycle management
src/lib/ testable computation and parsing logic
src/tools/ one lazy-loaded Vue component per tool
src/workers/ browser workers for expensive file operations
server/ static server and navigation configuration API
shared/tool-catalog.json authoritative tool metadata
shared/default-navigation.json first-run navigation order
tests/ unit and server integration tests
public/ browser icons and Web App Manifest
New tools must keep their computation independent, register the same stable ID in the catalog, default navigation, and lazy-load registry, reuse the shared UI, define resource limits where appropriate, and include normal, invalid, boundary, and known-vector tests. File tools matching the existing parse-then-calculate Worker protocol should reuse FileDropField and useTransactionalFileWorker, while keeping tool-specific algorithms, Worker messages, and Vue state separate. Candidate replacement must not destroy active state before parsing succeeds. Routes are generated from the tool registry; ordinary tools do not add routes manually.
RSA generation and verification use Web Crypto first and dynamically load the bundled node-forge fallback chunk from the same origin only when the native provider is unavailable or fails. Tool components remain lazy-loaded; the project does not add a Service Worker or duplicate the Brotli/Gzip compression normally supplied by a production reverse proxy such as Cloudflare.
Only fingerprinted files under dist/assets/ receive long-lived immutable caching. HTML, icons, the Manifest, and other stable filenames use no-cache so deployments can update them without waiting for a one-year browser cache to expire. XML validation identifies browser parser failures by their dedicated namespace, so a valid user element named parsererror is not rejected.
The browser icon set follows the sidebar brand and includes SVG, multi-frame ICO, Apple touch, 192/512, and maskable assets. The manifest supplies metadata only: the project deliberately has no Service Worker, offline cache, install prompt, or splash-screen bundle, so a deployment update cannot be hidden by application-managed stale caches.
The page exposes one product description through both the standard HTML description and an identical og:description compatibility field. It has no custom share image, other Open Graph metadata, platform crawler, or platform-specific fields. Sharing clients may fall back to the document title and existing favicons, but each platform controls its final preview and cache refresh behavior.
For the complete extension procedure and AI handoff rules, read AGENTS.md and README.zh-CN.md before editing. Inspect the Git worktree first and preserve existing changes.
Documentation
- README.zh-CN.md: authoritative product, deployment, behavior, extension, and release documentation
- AGENTS.md: mandatory instructions for AI and coding agents
- CHANGELOG.md: release history and verification records
- THIRD_PARTY_NOTICES.md: third-party licenses