images-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev b674d6e71b51
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 604467e480f8468389092a3b
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
AGENTS.md
# Images

Images is a set of free image tools that run entirely in the browser: compress, resize, convert and remove backgrounds. It is a free alternative to TinyPNG, iLoveIMG, Squoosh-style converters and remove.bg, and an OpenApp in the OpenApps free apps store (https://free-apps.openapps.xyz/), owned by the OpenApps team.

## What it promises

- Images never leave the person's device. Nothing is uploaded, ever: no server step, no analytics on image contents. Never add a feature that sends an image or its contents anywhere. The only third-party requests are the pinned background model downloads, which carry no image data.
- Free, with no limit on images or file size, no watermark, no account and no paid tier. Never add a cap, an upsell or tracking.
- Photo details (EXIF, GPS location, XMP, comments) are removed by default.
- Never hand back a bigger file than the person gave for the same job: if a fresh copy of the same format and size comes out larger, the original is returned (with photo details removed).

## What it does

Add any number of images (JPG, PNG, WebP, AVIF, HEIC, GIF first frame, BMP) by dropping, choosing or pasting them. One settings panel applies to all of them: remove background (clear, white, a picked color, or a blurred copy of the photo); convert to JPG, PNG or WebP (AVIF only when the browser can save it); quality for JPG and WebP; PNG as up to 256 colors or lossless; resize by width, height or percent, keeping the shape; remove photo details. Every image shows its new format, pixel size, file size and saving, updated as settings change. One image is shown large; drag across it (or use the arrow keys) to compare before and after. With several, a row opens the same comparison in a dialog. Download one image or all as a zip; on phones, Share hands them to the share sheet (Save Image puts them in Photos on iPhone).

Links carry settings, so an assistant can send a ready preset: `?bg=remove|white|blur|<hex>`, `to=jpg|png|webp|avif`, `quality=1-100`, `colors=all`, `width=` / `height=` / `percent=`, `details=keep` (`fromQuery` and `toQuery` in `src/lib/formats.ts`; the address updates as settings change). `public/llms.txt` documents them; keep the two in sync.

It does not crop, rotate, filter, add text, upscale, keep animation, put a photo behind a cut-out, or offer a brush to touch up a cut-out.

## How it is built

- `index.html` is the static landing page that search engines and AI crawlers read. Keep its copy, comparison, FAQ and JSON-LD in sync with what the app does.
- `src/Workspace.tsx` is the whole tool. It mounts into the landing hero (`#workspace`); once images are added, `body.app-mode` hides the landing sections. It keeps each image's source as a Blob (never decoded pixels, so many large photos fit in memory) and runs one job at a time per worker, always with the latest settings. A result counts only while it matches the current settings; while an image is made again its last result stays in place, dimmed. Images that fail show why with Try again, and the rest can still be downloaded.
- The look comes from the shared kit (`public/kit.css`, copied from the store's brand folder): the dialog (a bottom sheet on phones), action bar, skeletons, toasts and enter and leave motion are the kit's.
- `src/lib/formats.ts` holds the settings, the output format rules and the resize math. `src/lib/meta.ts` removes photo details from JPEG, PNG and WebP without touching pixels, and copies EXIF into a new JPEG when the person keeps details.
- `src/lib/codec.worker.ts` opens, resizes and encodes off the main thread: MozJPEG (`@jsquash/jpeg`), libwebp (`@jsquash/webp`), UPNG.js for 256-color PNG and oxipng (`@jsquash/oxipng`) for every PNG. MozJPEG made JPGs about 25% smaller than the browser's encoder at the same quality, which is why it is used. It also lays a cut-out on its new background. The blur is made from the background with the subject taken out, blurred wider and wider underneath to fill the gap, so the subject's colors leave no halo; it uses the canvas `filter` where the browser has it, and a shrink-and-enlarge where it does not.
- `src/lib/engine.ts` talks to the workers and decodes HEIC with `heic-to` (libheif) when the browser cannot (everything but Safari). `heic-to` is loaded only for HEIC files.
- `src/lib/cutout.worker.ts` removes backgrounds with the ISNet general model (DIS, Apache-2.0; ONNX export by IMG.LY, MIT; int8 weights by xrds/isnet-general-onnx-int8, MIT) on onnxruntime-web, using WebGPU when the browser has it and the processor otherwise. It loads only when someone turns background removal on. The model (44 MB, Hugging Face at a fixed commit) and onnxruntime's WebAssembly (27 MB, jsDelivr at the pinned npm version) are listed in `src/lib/model.ts` with their SHA-256; the worker downloads them once, refuses a file whose hash differs, and keeps them with the Cache API. They are not part of the site: a site deployed with its source must compress under 24 MiB. When you bump onnxruntime-web, update its version and hash in `model.ts`.
- There is no API and no data. `policy.json` has one collection that refuses everything, because the app is a Bounded app only for hosting. Images must not leave the device, so a server function would break the promise.
- `public/llms.txt` tells AI assistants that Images is browser-only, when to send people to it and how to build a link with settings. `public/index.md` is the landing page as markdown; keep it, the landing FAQ and the JSON-LD in sync.
- Keep `dist/` small (about 5 MB today, most of it the HEIC decoder): a site deployed with its source must compress under 24 MiB, and source sync skips files over 5 MiB.

## Working on it

`npm install && npm run build` typechecks and builds `dist/`. Ship changes through previews and releases as your runtime instructions describe; the app is an OpenApp, so nobody deploys it directly.

Check a change in a real browser: drop a large PNG, a JPG with GPS data and a turned (EXIF orientation) photo, a transparent PNG, a HEIC photo and a WebP. Check that sizes drop, that resize gives the exact pixels asked for, that pasting a screenshot adds it, that a link such as `/?bg=white&to=jpg` opens with those settings, that every download opens, that the GPS data is gone (and kept when the person turns removal off), and that background removal gives a transparent PNG and a white JPG. Test at phone width too.

## Voice

Plain words, short sentences, no jargon, no em dashes. Say what happens, not how clever it is.

Change history

Quality pass: background removal, blur background, paste images
b674d6e71b · 5 hours ago
Bounded source sync
c6622bcbd1 · 1 day ago
Bounded source sync
92ecc89502 · 1 day ago
Bounded source sync
ae2f8b8be0 · 1 day ago