Getting started

Install Kiri and get your first crop working.

Install

Plain <script> tag (no build step)

<link rel="stylesheet" href="node_modules/@michaelyagi/kiri/dist/kiri.min.css" />
<script src="node_modules/@michaelyagi/kiri/dist/kiri.min.js"></script>

Kiri lands as a global. Both a minified pair (kiri.min.js/kiri.min.css) and an unminified pair (kiri.js/kiri.css) ship in dist/ — use the unminified pair when you need to debug directly in devtools.

npm / ESM

npm install @michaelyagi/kiri
import { Kiri } from "@michaelyagi/kiri";
import "@michaelyagi/kiri/kiri.min.css";

Zero-config quickstart

The container element must already exist in the DOM before you construct Kiri — that's why the <div> comes before the <script> below. Constructing against a container that doesn't exist yet throws a clear error rather than a cryptic native one.

<div id="cropper"></div>

<script>
  const cropper = new Kiri(document.getElementById("cropper"), {
    frame: { shape: "circle", width: 200, height: 200 },
  });

  await cropper.load("photo.jpg"); // File, Blob, or URL string

  const blob = await cropper.export({ type: "blob", format: "image/png" });
</script>

No CSS is required on #cropper — the stage auto-sizes itself to the frame's dimensions (autoSizeStage: true by default). See Settings to size it via your own CSS instead.

Loading an image

load() accepts a File (e.g. from an <input type="file">), a Blob, or a plain URL string:

fileInput.addEventListener("change", async () => {
  const file = fileInput.files[0];
  if (file) await cropper.load(file);
});
EXIF orientation is corrected automatically on load (useExifOrientation: true by default) — a photo taken on its side from a phone camera displays right-side up.
Next: Methods — every method Kiri exposes.