A CLI to build IIIF collections

biiif (build iiif) 👷✨📃

npm i biiif --save
const { build } = require('biiif');
build('myfolder', '');

Organise your files according to a simple naming conventionto generate IIIFcontent/data using 100% node.js! Datand IPFScompatible.

Use biiif-clito run from a terminal.

Note: This uses the IIIF Presentation API v3(currently in beta), but is compatible with the Universal Viewerv3 (in beta).

If you want to build a website with biiif, try uv-app-starterwhich comes with the Universal Viewerand biiif already set up.

Building static sites with biiif workshop:


folderstringThe source folder of your IIIF collection/manifest on disk
urlstringThe Url to use as the root for all generated manifest, asset identifiers
generateThumbsbooleanGenerate thumbnails for images (100 x 100px)
virtualNamestringOverrides the source folder name when generating identifiers e.g. a dat archive id you need to appear in Urls instead of the source folder name


A collection is a folder with sub-folders whose names do notstart with an underscore.

A manifest is a folder with sub-folders whose names dostart with an underscore.

A collection's sub-folders (no underscore) are treated as further nested collections.

A manifest's sub-folders (with underscore) are treated as canvases to add to the manifest.

Files within 'canvas folders' (.jpg, .pdf, .mp4, .obj) are annotated onto the canvas with a paintingmotivation.


IIIF Presentation 3.0 uses the Web Annotation Data Modelto annotate canvases.

By default, biiif will annotate any files it finds in a canvas directory (except info.ymland thumb.jpg) onto the canvas with a paintingmotivation.

This is handy as a quick way to generate simple manifests. However, what if you want to annotate some text onto a canvas with a commentingmotivation?

Or what happens when you have obj or gltf files that require image textures to be located in the same directory? You don't want these files to be annotated onto the canvas too!

This is where custom annotations come in. Just create a file my-annotation.ymlin the canvas directory and set the desired properties in that.

For example, here is my-comment.yml:

motivation: commenting
value: This is my comment on the image

Here we've excluded the type(TextualBodyis assumed), and format(text/plainis assumed).

What about the gltf example? Here's how my-3d-object.ymlcould look:

value: assets/myobject.gltf

Here we've excluded the motivation(paintingis assumed), type(PhysicalObjectis assumed), and format(model/gltf+jsonis assumed).

biiif knows that because it's a gltf file, it's likely to have all of the above values. You just need to include a valueproperty pointing to where you've put the gltf file itself. In this case, an assetsfolder within the canvas directory. The associated image textures can live in the assetsfolder too, they won't get annotated unless you specifically ask for them to be.

Image Services

Here is an example of how to use an image service to describe your IIIF Level 0static tileset as a custom annotation:

In _tetons/tiles.yml, valueis set to the relative path to the info.jsonand a typeof Imageis used so that biiif knows to treat the info.jsonfile as an image service.

The tiles and info.jsonare located in _tetons/assets/tiles. These can be generated using this python script.

Ensure that the @idproperty in your info.jsonmatches the absolute URL where you will be hosting the tiles, e.g.


Metadata is not mandatory, but can be included as an info.ymlfile within a collection, manifest, or canvas folder. e.g.

label: The Lord of the Rings
description: The Lord of the Rings Trilogy
attribution: J. R. R. Tolkien
    License: Copyright Tolkien Estate
    Author: J. R. R. Tolkien
    Published Date: 29 July 1954

Here's an example of an info.ymlsupplying descriptive + rights properties and metadata for a gold-broach image manifest:

This manifest contains a single canvas folder _gold-broachwith an image to be painted onto the canvas. If there were many canvases in this manifest it might make sense to add an info.ymlto each subfolder with extra image-specific metadata.

Within the info.ymlyou can set the label, description, and attributiondescriptive and rights propertiesat the top-level. IIIF Presentation 3 (in beta) has renamed descriptionto summary, and attributionto requiredStatementbut these will still work in IIIF viewers.

Under these you can add a metadatasection that is essentially a list of key value pairs containing any info you like (there is deliberately no specification for this as the IIIF spec writers feel it falls outside of their remit).


To add a thumbnail to your collection, manifest, or canvas simply include a file named thumb.jpg(any image file extension will work) in the directory.

If no thumb image is found in a canvas directory, and the generateThumbsparameter is set to true, biiif checks to see if an image is being annotated onto the canvas with a painting motivation. If so, a thumb is generated (100 x 100px) from that.

Linked Manifests

Often it's necessary to include IIIF manifests in your collection from elsewhere. To do this, include a manifests.ymlfile in your collection folder e.g.

- id:
  label: Linked Manifest 1
- id:
  label: Linked Manifest 2
- id:

If you leave the labelproperty blank, it will default to the name of the last folder in the idURL.

Including a manifests.ymlfile in a folder without any sub-folders forces it to behave like a collection.


MozFest zine workshop published on glitch:

A repo of test manifests:

Collection for the Nomad Project:

IIIF 3D manifests:


Here is an example of how to organise your files/folders for biiif.

This example only has a single root collection, but biiif will happily build collections to any nested depth.

biiif will accept a manifest folder too, generating a single manifest index.json.

lord-of-the-rings                  // collection
├── info.yml                       // collection metadata
├── thumb.jpg                      // collection thumbnail
├── 0-the-fellowship-of-the-ring   // manifest
|   ├── _page-1                    // canvas
|   |   ├── page-1.jpg             // content annotation
|   |   └── info.yml               // canvas metadata
|   ├── _page-2                    // canvas
|   |   ├── page-2.jpg             // content annotation
|   |   └── info.yml               // canvas metadata
|   ├── _page-n                    // canvas
|   |   ├── page-n.jpg             // content annotation
|   |   └── info.yml               // canvas metadata
|   ├── info.yml                   // manifest metadata
|   └── thumb.jpg                  // manifest thumbnail
├── 1-the-two-towers               // manifest
|   ├── _page-1                    // canvas
|   ├── _page-2                    // canvas
|   ├── _page-n                    // canvas
|   ├── info.yml                   // manifest metadata
|   └── thumb.jpg                  // manifest thumbnail
└── 2-the-return-of-the-king       // manifest
    ├── _page-1                    // canvas
    ├── _page-2                    // canvas
    ├── _page-n                    // canvas
    ├── info.yml                   // manifest metadata
    └── thumb.jpg                  // manifest thumbnail








扫码加入 JavaScript 社区