Free file tools that run entirely in your browser. Live at tools.dcln.me.
No uploads. No accounts. No ads. No cookies. Open source under MIT.
Most online file tools upload your file to a server, process it there, and offer you the result. The privacy promises are typically "we delete it after an hour" — not "we never had it."
Modern browsers can do this work locally. So that's what these tools do.
| Slug | Status | Modes |
|---|---|---|
pdf |
live | Merge, split, rotate, organize, images→PDF, PDF→images |
image |
live | Convert, resize, compress, favicon bundle, strip EXIF, SVG→raster |
data |
soon | CSV / JSON / YAML / XML / TOML / Excel — convert, format, validate, type-gen |
audio-video |
soon | WebCodecs-based audio + video conversion, trim, compress, extract audio |
Each product family lives at a single URL (/pdf, /image, etc.) with operations exposed as tabs inside the tool. No per-operation URLs — one hub per product.
- Astro 6 — multi-page output, islands architecture
- Preact — interactive widgets (~10 KB instead of React's ~45 KB)
- Tailwind v4 — via the
@tailwindcss/viteplugin - pdf-lib + pdfjs-dist — PDF write + read
- fflate — ZIP packaging for multi-file outputs
- libheif-js + @jsquash/avif + utif2 — image codecs not natively supported by the browser
- Cloudflare Workers Static Assets — hosting
- Cloudflare R2 at
cdn.dcln.me— for WASM blobs that exceed the 25 MiB per-asset cap
Node 22+ required.
npm install
npm run dev # local dev server at http://localhost:4321
npm run build # production build → dist/
npm run preview # serve the production build locally
npm run test:e2e # Playwright suiteDeploys automatically to Cloudflare Workers Static Assets via Workers Builds on
push to main. Manual deploy:
npm run build
npx wrangler deploywrangler.toml configures the asset directory and the not_found_handling
strategy.
Modes share a hub (PdfHub.tsx, ImageHub.tsx, …). To add one:
- Library at
src/lib/<area>/<op>.ts— framework-agnostic, unit-testable. - Worker at
src/lib/<area>/<op>.worker.tsif the work is heavier than ~50 ms — wraps the lib in apostMessageinterface. - Panel at
src/components/tools/<PanelName>.tsx— Preact, manages its own state, usesFileDropZone+lib/util/filehelpers. - Register in hub — add a
Modeliteral and aModeSpecblurb to the hub component, plus a conditional render block. - E2E — extend the relevant
e2e/<hub>.spec.tswith a tab-click + round-trip test.
- Hub at
src/components/tools/<Family>Hub.tsxmodelled onPdfHub.tsx. - Page at
src/pages/<family>.astro— usesToolLayout.astro, sets title/description, includesHowTo+FAQPage+BreadcrumbListJSON-LD. - Homepage card in
src/pages/index.astro— add to thetoolsarray, status"live". - E2E at
e2e/<family>.spec.ts. - Sitemap is automatic.
- If WASM > 1 MB — upload to R2 at
cdn.dcln.me/<lib-name>/<version>/<file>and load from there. Pin the version.wrangler r2 object put dcln-assets/libheif/1.19.8/libheif.wasm --file=./libheif.wasm
- Lighthouse ≥95 across Performance, Accessibility, Best Practices, SEO. Release blocker.
- Drag-and-drop must have a keyboard-accessible fallback (visible click-to-select button, arrow buttons for reordering).
- ARIA live region for progress and completion.
- "Files never leave your browser" copy visible above the fold.
- No third-party scripts beyond Cloudflare Web Analytics. No cookie banner.
This project uses Conventional Commits. Every commit and PR title must follow the pattern:
type(optional-scope): short description
Types: feat, fix, docs, style, refactor, perf, ci, chore, test, build, revert.
For new modes, use the family slug as the scope:
feat(image): add SVG → raster mode
fix(pdf): handle password-protected PDFs gracefully
ci: bump lighthouse threshold to error-level 0.95
commitlint validates commits on every PR via the Commit Messages job in .github/workflows/ci.yml. Past commits made before this convention was added are not retroactively validated.
MIT. See LICENSE.