DEV Community

KAAN TOKALI
KAAN TOKALI

Posted on

I Built Two Browser Tools That Developers Actually Need — No Upload, No Backend, No BS

Cross-posted from omnvert.com — a growing collection of free, privacy-first web tools.


I got tired of the same experience every time I needed a quick file conversion:

  1. Google "heic to jpg online" or "csv to json converter"
  2. Land on a site with 14 ads, a file size limit, and a spinner that uploads my file to god-knows-where
  3. Wait. Wonder if my data is now on some server in a basement somewhere.
  4. Download the result.

So I built two tools into Omnvert that do this differently: everything runs in your browser, nothing touches a server, and the tools are fast enough that you barely notice the conversion happened.

Here's what I built, why, and the interesting technical parts.


Tool 1: HEIC → JPG / PNG Converter

The problem

Apple switched iPhones to HEIC format back in iOS 11 (2017). It's genuinely better than JPEG — similar visual quality, roughly half the file size. The problem is that the rest of the world never got the memo.

Try to upload a photo from your iPhone to:

  • A web form
  • Figma
  • Google Slides
  • Most CMS platforms
  • Windows Photo Viewer (without a codec pack)

Most of them either reject the file silently or show a broken image icon. So every iPhone user periodically needs to convert HEIC to JPG, and most of the tools for this upload your photos to a server.

The irony: HEIC files often contain your GPS location, device information, and timestamps in their EXIF metadata. These are exactly the kind of files you don't want to upload to a random server.

The solution

The tool uses heic2any, a library that decodes HEIC using WebAssembly in the browser. No server involved.

import heic2any from 'heic2any';

const converted = await heic2any({
  blob: heicFile,
  toType: 'image/jpeg',
  quality: 0.85
});
Enter fullscreen mode Exit fullscreen mode

That's the core of it. The rest is UX: batch processing, progress indicators per file, before/after file size display, and ZIP download for multiple files using JSZip.

One thing that surprised me

HEIC decoding is slow. Not "annoying" slow — I mean 1–3 seconds per image in the browser. HEIC uses HEVC compression, which is computationally expensive to decode. The WASM runtime handles it but it's doing real work.

This means the UX needs to communicate progress clearly. A spinner that runs for 2 seconds feels like a frozen app. A per-file progress bar that says "Converting image 3 of 7..." feels fast, even if it takes the same time.

The iOS Safari quirk

The ironic part of building a HEIC converter: the people who most need it are iPhone users, and iOS Safari has its own opinions about file inputs. Testing on actual iOS Safari was essential — the file picker behavior for .heic files is slightly different from desktop Chrome, and getting tap-to-upload working correctly took a few iterations.

Try it: omnvert.com/en/tools/heic-to-jpg


Tool 2: CSV ↔ JSON Converter

The problem

This one comes up constantly in development work. You have:

  • A CSV export from a database, analytics platform, or spreadsheet
  • You need it as JSON for an API, config file, or JavaScript import
  • Or the reverse — a JSON array from an API that needs to go into a spreadsheet

The manual process is either "write a script real quick" (which takes longer than it should) or use an online tool that uploads your data somewhere.

The "upload your data" part is a real problem when the CSV contains user emails, internal analytics, or anything you wouldn't want on a stranger's server.

What the tool does

It's bidirectional. Two tabs: CSV → JSON and JSON → CSV.

CSV → JSON gives you options:

Input CSV:
name,age,active
Alice,30,true
Bob,25,false

Output (array of objects):
[
  { "name": "Alice", "age": 30, "active": true },
  { "name": "Bob", "age": 25, "active": false }
]
Enter fullscreen mode Exit fullscreen mode

The type inference feature is the one I find most useful. Without it, everything comes out as strings — "age": "30" instead of "age": 30. With it enabled, numbers become numbers, booleans become booleans, and empty/null values become actual null.

JSON → CSV handles the annoying edge cases:

Nested objects are a common pain point. If your JSON looks like:

[
  { "name": "Alice", "address": { "city": "Istanbul", "country": "TR" } }
]
Enter fullscreen mode Exit fullscreen mode

The tool flattens it to dot notation:

name,address.city,address.country
Alice,Istanbul,TR
Enter fullscreen mode Exit fullscreen mode

Not perfect for deeply nested structures, but it handles the one-level nesting that covers probably 80% of real-world cases.

Delimiter auto-detection handles the European vs. American CSV difference. European Excel exports often use semicolons instead of commas (because commas are decimal separators in many European number formats). The tool detects comma, semicolon, and tab automatically, or you can force a specific delimiter.

The library

The heavy lifting is done by PapaParse, which is genuinely excellent. It handles edge cases in CSV parsing that you really don't want to implement yourself — quoted fields with commas inside them, newlines inside quoted fields, BOM characters, inconsistent line endings.

import Papa from 'papaparse';

// CSV → JSON
const result = Papa.parse(csvString, {
  header: true,
  skipEmptyLines: true,
  dynamicTyping: typeInferenceEnabled
});

// JSON → CSV
const csv = Papa.unparse(jsonArray, {
  delimiter: selectedDelimiter
});
Enter fullscreen mode Exit fullscreen mode

dynamicTyping: true is PapaParse's built-in type inference. When it's on, it handles numbers and booleans automatically. The custom inferType function I added handles the null/NULL/empty string → null cases that PapaParse doesn't cover.

Live conversion

The output updates as you type, debounced at 300ms. This makes the tool feel like a REPL rather than a form you submit. For large files (above ~500KB), there's a warning since live conversion can get sluggish — but you can still trigger it manually with Ctrl+Enter / Cmd+Enter.

Try it: omnvert.com/en/developer-tools/csv-json


The privacy angle

Both tools share the same philosophy: your files never leave your device.

This isn't a marketing claim — it's the architecture. There's no backend endpoint receiving files. The conversion code runs in your browser using JavaScript and WebAssembly. You can open DevTools → Network tab while using either tool and watch: zero file upload requests.

For HEIC files this matters because they contain EXIF data including GPS coordinates. For CSV files this matters because they often contain user data, internal metrics, or anything else you'd rather not upload to an unknown server.

The privacy note on both tool pages is honest about what this means: it also means there's a file size ceiling (browser memory limits) and conversion speed depends on your device, not a server.


What's next

Omnvert has about 80 tools across image processing, PDF manipulation, network diagnostics, and developer utilities. The two tools above were the most requested additions based on what people were searching for and not finding as clean browser-based solutions.

If you run into edge cases, the feedback button on each tool page goes directly to me.


Both tools are free, require no signup, and work in any modern browser. Built with Next.js, PapaParse, heic2any, and a lot of testing on iOS Safari.

omnvert.com — Free tools for developers and everyday use.


Tags: #webdev #javascript #tools #opensource

Top comments (0)