npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cozy-iiif

v0.7.2

Published

A developer-friendly collection of abstractions and utilities built on top of @iiif/presentation-3 and @iiif/parser

Downloads

635

Readme

cozy-iiif

A developer-friendly TypeScript API for working with IIIF resources. Built on top of the IIIF Commons @iiif/presentation-3 and @iiif/parser libraries.

Features

  • Resource identification for any URL: IIIF collection and presentation manifests, image services, static image, and more.
  • Developer-friendly TypeScript API for parsing and working with IIIF resources.
  • Seamless upgrade from IIIF Presentation API v2 to v3 (using @iiif/parser under the hood).
  • Preserves access to underlying @iiif/presentation-3 types.
  • Utilities for stitching thumbnails and cropping regions from IIIF Level 0 tilesets and simple image manifests.
  • Helpers for reading and writing annotations on Canvases and Presentation manifests.

Installation

npm install cozy-iiif

Basic Usage

Identify and parse a URL:

import { Cozy } from 'cozy-iiif';

const parsed = await Cozy.parseURL('https://www.example.com/manifest.json');

if (parsed.type === 'manifest') {
  const manifest = parsed.resource; // CozyManifest
  console.log(`Presentation API ${manifest.majorVersion}`);
} else if (parsed.type === 'collection') {
  const collection = parsed.resource; // CozyCollection
  console.log(`Collection, Presentation API ${collection.majorVersion}`);
} else if (parsed.type === 'iiif-image') {
  const image = parsed.resource; // CozyImageResource
  console.log(`Image API ${image.majorVersion}`);
} else if (parsed.type === 'plain-image') {
  console.log('Plaing (JPEG or PNG) image');
} else if (parsed.type === 'webpage') {
  console.log('URL points to a web page!');
} else if (parsed.type === 'error') {
  console.log('Error:', parsed.code, parsed.message);
}

Alternatively, you can parse an existing JSON object.

const json = await fetch('https://www.example.com/manifest.json').then(res => res.json());
Cozy.parse(json);

Cozy provides normalized utility types for key IIIF entities: CozyManifest, CozyCanvas, CozyRange, CozyImageResource, CozyCollection, etc. Each utility type provides helpers to simplify common access operations (e.g. metadata, labels in different locales, etc.) and retains the original source data as a source field.

// Parsed CozyManifest
const manifest = parsed.resource;

// Default
console.log(manifest.getLabel()); 

// For locale (with fallback)
console.log(manifest.getLabel('de'));

// Metadata as normalized CozyMetada[]
console.log(manifest.getMetadata());

// The raw source data, @iiif/presentation-3 typed
console.log(manifest.source);

Thumbnail Helper

CozyCanvas has a simple helper for getting a Thumbnail URL. The URL will use the thumbnail property of the original resource if available, or the image service otherwise.

const firstCanvas = manifest.canvases[0];

// With default size (400px smallest dimension)
console.log(firstCanvas.getThumbnailURL());

// With custom minimum smallest dimension
console.log(firstCanvas.getThumbnailURL(600));

Table of Contents Helper

cozy-iiif includes a utility to easily get a table of contents for a Presentation manifest, based on the manifest's structures property.

// Returns a list of CozyTOCNode objects.
const toc = manifest.getTableOfContents(); 

const logTOCNode = (node: CozyTOCNode) => {
  console.log(node.getLabel());
  node.children.forEach(logTOCNode);
}
    
root.forEach(logTOCNode.root);

Image Types and Levels

The CozyImageResource provides a helper properties that identify the type and level of an image.

const firstCanvas = manifest.canvases[0];
const image = firstCanvas.images[0];

console.log(image.type); // 'static', 'dynamic' or 'level0';

Dynamic images are served from an image server and have helpers to retrieve specific region URLs.

const bounds = {
  x: 100,
  y: 100,
  w: 320,
  h: 240
};

// With default minimum shortest dimension (400px);
console.log(image.getRegionURL(bounds));

// With custom minimum shorted dimension
console.log(image.getRegionURL(bounds, 800));

// Full image with custom minimum shorted dimension
console.log(image.getImageURL(800));

// Resolves the actual image pixel size from the info.json
// or the image file (which may **differ**) from the canvas size!
console.log(image.getPixelSize());

Level 0 Utilities

Working with a Level 0 tileset, but need a thumbnail, or crop a region? The cozy-iiif/level-0 module has you covered! Cozy uses Web workers for background image processing and request throttling when harvesting tilesets for stitching. Stitched images are harvested at the smallest possible size, to keep things fast and prevent unnecessary downloads.

Thumbnails

import { getThumbnail } from 'cozy-iiif/level-0';

const firstImage = canvas.images[0];
if (firstImage.type !== 'level0') {
  // Normal thumbnail URL (string)
  console.log(canvas.getThumbnailURL());
} else {
  getThumbnail(firstImage).then(blob => {
    // Creates a data URL you can use as `src` for an image
    console.log(URL.createObjectURL(blob));
  });
}

Regions

import { cropRegion } from 'cozy-iiif/level-0';

const firstImage = canvas.images[0];

const bounds = {
  x: 100,
  y: 100,
  w: 320,
  h: 240
};

if (firstImage.type === 'level0') {
  cropRegion(firstImage, bounds).then(blob => {
    console.log(URL.createObjectURL(blob));
  });
}

Cozy Annotation Helpers

Utilities for working with annotations on on Canvases.

Fetch Annotations on Canvas

This helper fetches all annotations on a canvas, regardless of whether they are embedded in the manifest, or referenced via URL (incl. through Annotation Collections).

import { fetchAnnotations } from 'cozy-iiif/helpers';

const firstCanvas = manifest.canvases[0];

const annotations = await fetchAnnotations(manifest.canvases[0]);
console.log(annotations);

Import Annotations Into Manifest

This helper programmatically imports annotations into an existing manifest as embedded annotations.

import type { Annotation } from '@iiif/presentation-3';
import { importAnnotations } from 'cozy-iiif/helpers';

const annotations: Annotation[] = [{
  id: 'https://iiif.io/api/cookbook/recipe/0021-tagging/annotation/p0002-tag',
  type: 'Annotation',
  motivation: 'tagging',
  body: {
    type: 'TextualBody',
    value: 'Gänseliesel-Brunnen',
    language: 'de',
    format: "text/plain"
  },
  target: 'https://iiif.io/api/cookbook/recipe/0021-tagging/canvas/p1#xywh=265,661,1260,1239'
}];

// Generates a new CozyManifest with annotations from an original CozyManifest.
const updated = importAnnotations(original, annotations);

// The source field has the raw manifest JSON (annotations included!)
console.log(updated.source);

License

MIT License - see the LICENSE file for details.