tools
English · Bahasa Indonesia
My everyday file toolbox, built for the file work I do every day and published free for everyone.
72 tools for PDF, Office files, images, video, audio and QR codes, and every one of them runs entirely in your browser.
Your files are never uploaded.
▶ Watch the 16-second launch video with sound · Bahasa Indonesia version
Why
Most "free online converters" upload your file to someone else's server. For a contract, a payslip
or an ID scan, that is a bad trade. This site makes one promise and is built around it:
everything happens on your device. There is no backend, no account, no upload and no
third-party processing API. Heavy work is done with libraries compiled to WebAssembly or with the
browser's own media encoders, and a library is downloaded only when you open the tool that needs it.
- Free and open source (MIT)
- Bilingual UI: English and Indonesian, with a toggle in the header
- Installable app: add it to a phone's home screen or a desktop ("Install app" in the header); it opens without browser bars, and every tool you have opened once keeps working offline
- Full screen instruments: piano, guitar and drums have a full-screen mode that turns a phone sideways
- Embeddable: any tool can go on your own site through an iframe, and the first tool is packaged
as a web component (below)
Tools
All 45, grouped the way the home page groups them. Each name links to the live tool.
To PDF
- Word to PDF:
.docx to PDF, paginated without cutting through lines of text
- Images to PDF: reorder, rotate, A4/Letter/fit-to-image; phone EXIF rotation applied
- PowerPoint to PDF:
.pptx to PDF, one page per slide
- Excel to PDF:
.xlsx/.csv to a selectable-text PDF table, with theme colors, borders, merged cells and number formats
From PDF
- PDF to Word: editable
.docx, keeping font size, bold/italic, tabs and page breaks
- PDF to Excel: tables rebuilt from text positions; currencies and percentages become real numbers
- PDF to PowerPoint: one slide per page, with the text as editable text boxes
- PDF to Images: PNG/JPG at 72, 150 or 300 dpi, zipped when there are several
- PDF to Markdown: headings, emphasis, lists and tables, with tables joined across pages
Edit & Secure PDF
- Merge PDF, Split PDF (pages, ranges like
1-3, 5, 8-, or every N pages)
- Watermark PDF: text or logo, centred or tiled, correct on rotated pages
- Organize PDF Pages: thumbnails you drag to reorder, rotate, duplicate or delete
- PDF Page Numbers: position, format (
1, 1 / 10, Page 1) and the first numbered page
- Sign PDF: draw (pressure-sensitive) or upload a signature, then place it anywhere
- Compress PDF: re-encodes embedded JPEGs and optimises the structure with qpdf; never returns a larger file
- Protect PDF (AES-256 password and permissions) and Unlock PDF
Images & Media
- Compress Images: batch JPG/WebP, metadata (including GPS) stripped
- Crop & Resize Image: free or fixed ratios, rotate, flip, exact pixels
- Convert Image Format: HEIC (iPhone), WebP, AVIF, PNG, JPG to JPG/PNG/WebP, in batches; HEIC decoded by a self-hosted libheif wasm
- ID Photo: 2×3 / 3×4 / 4×6 crop, red/blue/white backdrop, 4R or A4 print sheet (JPG/PNG/PDF)
- Remove Photo Metadata: shows camera, date and GPS; JPG/PNG are cleaned losslessly
- Remove Background: magic wand, color select, lasso and brush, with no AI model to download
- Compress Video: MP4 output using the device's own encoder, with a size estimate up front
- Trim Video & Audio: filmstrip/waveform timeline; untouched parts are copied without re-encoding
- GIF ⇄ MP4, Extract Video Frames
- Change Speed: 0.25× to 4× with the pitch kept natural (a hand-written WSOLA time-stretch)
- Merge Audio, Compress Audio (MP3, AAC or Opus)
- : screen, window or tab, with mic and tab audio mixed, a floating camera, and WebM or MP4 export
Music
- Guitar Tuner: microphone pitch detection (McLeod method), auto string detection, guitar/bass/ukulele/violin/viola/cello tunings, reference tones, continuous drone, adjustable A4
- Metronome: 30–300 BPM on a lookahead Web Audio scheduler, accents, beats per bar, subdivisions, tap tempo
- Chord Finder & Transpose: guitar and ukulele shapes generated for every root and 16 chord types, playable (Karplus–Strong); transposes a pasted song sheet keeping chords aligned to the lyrics
- Chord Progression Builder: 12 patterns (pop, 50s, canon, ii–V–I, 12-bar blues, minor loops) in any key built from the chord dictionary's generated shapes; plays on the guitar or piano synth with a lookahead scheduler, transposes by semitone, opens the chords in Online Guitar
- Practice Recorder: raw microphone take over a lookahead metronome (the click is never recorded), count-in bar, playback with the click laid back on top and a nudge for latency, MP3/M4A/WAV export through Mediabunny
- BPM & Key Finder: tempo from an onset-envelope comb search, key from a chromagram against Krumhansl profiles, Camelot code and diatonic chords; runs in a Web Worker
- Online Piano: all 88 keys with a minimap and 1–7 octave views; six synthesised voices (grand, electric piano, organ, harpsichord, strings, music box); practice mode with public-domain pieces, scales and any MIDI file you open (parsed in the browser), next-key highlighting, demo playback and a score; multi-touch, computer keyboard, Web MIDI, sustain, chord names
- Online Guitar: Karplus–Strong strings with a fractional-delay all-pass (in tune to ~2 cents) and pick-position excitation, acoustic body / clean / overdriven amp; swipe-to-strum over generated chord shapes, capo, free fretboard, auto accompaniment patterns
- : nine synthesised pads (808-style metal for hats and cymbals, hi-hat choke), multi-touch with centre-is-louder velocity, keyboard, General MIDI e-drum input; 16-step sequencer with accents, swing and nine preset grooves, saved in the browser
Developer & Design
- QR Code Generator: links, Wi-Fi, WhatsApp, vCard and more, with logo and styles; every code is scanned back to confirm it reads
- QR & Barcode Reader: from an image, a pasted screenshot or the camera (QR, Data Matrix, Aztec, PDF417, EAN/UPC, Code 128…)
- JSON Beautifier and JSON Minify: a custom parser that keeps numbers exactly as written
- Favicon Generator:
.ico, iOS/Android icons, web manifest and the <head> snippet
- Image ⇄ Base64, Color Picker (HEX/RGB/HSL/OKLCH, WCAG contrast, 50–950 shades)
Productivity
- Notes: Markdown with live checklists, saved in the browser, JSON backup/restore
- Calculator: basic and scientific, with its own expression parser (no
eval)
- Password Generator: random passwords and Indonesian/English passphrases from
crypto.getRandomValues, plus a strength check with estimated guessing time
- Word Counter: words, characters, sentences, paragraphs, reading/speaking time and per-platform character limits
- Unit Converter: length, weight (ons, quintal), area (hectare, are, tumbak), volume, temperature, speed and data
- Date Calculator: exact age, days between dates, working days with bundled Indonesian public holidays, add/subtract time
- Prayer Times: daily and monthly times from a bundled city list or GPS, computed from the sun's position (Kemenag angles: Fajr 20°, Isha 18°, Asr 1×, 2-minute margin), printable; no API
- Qibla Direction: great-circle bearing to the Kaaba plus a live phone compass via
DeviceOrientationEvent (iOS permission, calibration warning)
- Hijri ⇄ Gregorian Converter: through the browser's
islamic-umalqura Intl calendar, plus a year of Islamic holidays; notes that official Kemenag dates may differ by a day
- Zakat Calculator: income, wealth, gold/silver and fitrah zakat; nisab from a gold price you enter (nothing fetched), formulas shown
- Digital Tasbih: big tap counter with 33/99/free/custom targets, vibration at the target, keyboard shortcuts, history in localStorage
The Indonesian README has a longer per-tool table with every option and limitation.
How it works
src/
├── tools/
│ ├── registry.ts one entry per tool: slug, category, icon, keywords, lazy(() => import(...))
│ ├── registry-en.ts English titles and descriptions
│ └── <slug>/ one folder per tool, default-exported React component
├── lib/ shared engines: pdf-text, pdf-doc, qpdf, media, image, i18n, routing
└── components/
├── tool/ shared tool UI: FileDrop, MediaRange, SizeResult, ...
packages/screen-recorder/ the same tool source built as an npm package / web component
- One folder per tool, one registry entry. Adding an entry is all it takes: the home-page card,
the search index and the
#/<slug> route are all derived from the
registry. Each tool is React.lazy-loaded, and heavy libraries (pdf.js, ExcelJS, Mediabunny…)
are dynamic import()s inside the tool, so the home page never pays for them.
- Shared engines instead of copy-paste. PDF text extraction (
lib/pdf-text.ts) feeds PDF to
Word, Excel, PowerPoint and Markdown; PDF editing (lib/pdf-doc.ts, pdf-lib) handles rotated
pages and restriction-only encryption for merge, split, watermark and sign; all audio/video goes
through lib/media.ts on Mediabunny.
- WebAssembly, self-hosted. qpdf 12 compiled to wasm handles encryption and structural
optimisation (a fresh module per command, files in its in-memory FS). zxing-wasm reads barcodes,
with its
.wasm bundled by Vite instead of fetched from a CDN. MP3 and AAC encoders are wasm
fallbacks registered only when the browser has no native encoder.
- Hash routing under
/tools/. Routes are #/<slug> so a reload on GitHub Pages' sub-path never
404s and no server rewrite is needed.
- A light home page. A short static intro, then the searchable tool grid (press
/ to
search) grouped by category. No animation library and no per-frame JavaScript, so it opens fast
even on a phone.
- Bilingual by construction. Every string is written in both languages at the point of use
(
t('Indonesian', 'English')). English is the default unless the browser language is Indonesian
or Malay; ?lang=en in a link forces it.
More detail, including how the npm package isolates its styles in a Shadow DOM, is in
docs/ARCHITECTURE.md.
Tech stack
| Area | Libraries |
|---|
| App | React 19, TypeScript 6, Vite 8, Tailwind CSS v4, shadcn/ui, lucide-react, Geist font |
| PDF | pdf.js (legacy build), pdf-lib, qpdf (wasm), jsPDF + jspdf-autotable |
| Office | docx-preview, docx, ExcelJS + numfmt, pptxgenjs, @jvmr/pptx-to-html, html2canvas-pro, DOMPurify |
| Audio / video | Mediabunny on WebCodecs, @mediabunny/aac-encoder and mp3-encoder (wasm), gifenc, gifuct-js |
| Images / QR | Canvas 2D, zxing-wasm, node-qrcode |
| Music | Web Audio API only — pitch, tempo and key detection and the chord shapes are written in-house |
| Other | marked + DOMPurify (Notes), perfect-freehand (Whiteboard), JSZip |
Getting started
Requires Node.js 22 (the version CI uses).
npm ci
npm run dev # dev server
npm run build # type-check (tsc -b) + production build
npm run preview # serve the production build
npm run lint # oxlint
npm run build:packages # build the embeddable npm package(s)
npm run og # re-render the Open Graph image (needs Chrome/Chromium)
A local build uses base /. To reproduce the GitHub Pages build exactly:
npx tsc -b && npx vite build --base=/tools/ && npx vite preview --base=/tools/
Every push to main is built and deployed to GitHub Pages by
.github/workflows/pages.yml.
Adding a tool
- Create
src/tools/<slug>/ with a default-exported component. Reuse the shared UI in
src/components/tool/ and keep heavy libraries behind a dynamic import().
- Add one entry to
src/tools/registry.ts (category, icon, formats, search keywords, lazy import)
and its English text to src/tools/registry-en.ts.
The one rule: all processing stays on the client. No backend, and no sending user files to a
third-party service.
Quality gates
npm run build is the gate. It runs tsc -b (strict TypeScript) before vite build, and CI
runs the same type-check before every deploy, so a type error never ships.
- Lint with oxlint (
npm run lint).
- There is no automated test suite. Tools are verified by using them and by inspecting the
files they produce, which has caught bugs a click-through could not (see the lessons below).
- The npm package's hand-written public types are checked against the source at build time
(
packages/screen-recorder/types/check.ts).
Browser support
- Video and audio tools need WebCodecs. The UI checks for
VideoEncoder/AudioEncoder first
and names the browsers that support them when they are missing. AAC falls back to a wasm
encoder where the browser has none (Firefox, Chrome on Linux); MP3 always uses the wasm encoder.
- PDF tools use pdf.js's legacy build. pdf.js 6 relies on very recent JavaScript, and the modern
build made every PDF tool fail on older Chromium.
- Screen Recorder needs a desktop browser (
getDisplayMedia); it records VP9/Opus WebM, or MP4
on Safari, and can convert WebM to MP4.
- Smaller notes: the Color Picker's screen eyedropper needs the EyeDropper API (Chrome/Edge);
HEIC images open only in Safari.
Known limitations, also stated in each tool: scanned PDFs are not supported (that needs OCR);
legacy .doc, .ppt and .xls are not supported; Excel to PDF and Watermark PDF write text with
PDF's built-in Helvetica, so non-Latin scripts do not render correctly.
Embed a tool on your site
Any tool can be embedded. ?embed renders the tool alone, without the site header and footer;
add &theme=light|dark and &lang=en|id as needed.
<iframe
src="https://chalidade.github.io/tools/#/screen-recorder?embed&lang=en"
title="Screen Recorder"
style="width: 100%; height: 760px; border: 0; border-radius: 16px"
allow="display-capture; microphone; camera; clipboard-write; fullscreen; picture-in-picture"
></iframe>
packages/screen-recorder builds the Screen Recorder from the same
source into a <screen-recorder> custom element (React and CSS bundled, rendered in a Shadow DOM)
plus a headless API. It is ready to publish to npm as @chalidade/screen-recorder but has not been
published yet; until then, use the iframe.
Engineering notes
Things this project taught me, with the longer write-ups on my devlog:
- Paginating a .docx in the browser without cutting lines.
CVs built as one big layout table were sliced through a line of text at the page break. The fix
measures real rendered lines with
Range.getClientRects() and moves the cut into a gap; margins
moved to @page so continuation pages keep them.
- Rebuilding tables from PDF text.
A PDF has no tables, only positioned text. Rows come from shared baselines and columns from
vertical gutters no text crosses, with a tolerance so one long cell cannot erase a column.
- Time-stretching audio in the browser.
A streaming WSOLA implementation for speed changes without the chipmunk effect, with memory
bounded no matter how long the file is.
- Measure the output, not the click-through. Every tool passed a click-through, yet probing
the files found a 2× video with 81 frames instead of 120 and a GIF playing 4% fast.
- File contents are untrusted input. Slide HTML is sanitised with DOMPurify, the QR reader only
makes
http(s), mailto, tel and sms links clickable, and a crafted-.docx XSS in Word to
PDF (docx-preview rendering embedded HTML in an unsandboxed iframe) was fixed in
68db1ae.
- Scope calls follow from the promise. Background removal uses manual selection tools instead
of a ~100 MB AI model download, and a YouTube/Instagram downloader was turned down because it
cannot work without a server-side proxy.
How this was built
Built with Claude Code as the coding assistant. I decided what to
build and where to draw the scope lines, reviewed and merged every change, and tested the tools on
real files and on the outputs they produce.
License
MIT © Chalid Ade Rahman · chalidade.github.io