Artikel ini saat ini hanya tersedia dalam bahasa Inggris.

Image ManifestNov 21, 20257 min read

Building an Image Manifest for Repeatable Builds

An image manifest is a simple record that connects source files to generated outputs. It tells the team which original created which WebP, AVIF, JPEG, or PNG files, what settings were used, and whether the result passed review. Without a manifest, image optimization relies too much on folder names and memory.

Repeatable builds need that record. When a layout changes, a source image updates, or a CI job fails, the manifest helps the team regenerate the right files instead of guessing.

A filename list is not a repeatable image manifest. The record must prove source identity, generated outputs, tool settings, result status, review decision, and the page or component that consumes the asset.

Start With the Source#

Every manifest entry should identify the source image. At minimum, record the path:

{
  "source": "images/originals/homepage-hero.jpg"
}

For stronger tracking, include a hash or modified timestamp. This helps detect when a source file changed but the output was not regenerated.

{
  "source": "images/originals/homepage-hero.jpg",
  "sourceHash": "sha256:..."
}

The source should be the preserved original or approved working copy, not a generated WebP output.

Use relative repository paths, not local desktop paths. A manifest should work on another developer machine and in CI:

{
  "source": {
    "path": "images/originals/homepage-hero.jpg",
    "sha256": "sha256:...",
    "bytes": 842113,
    "role": "homepage-lcp-hero",
    "owner": "Marketing"
  }
}

The hash is valuable because modified timestamps can change during copy, checkout, or archive extraction. The role is valuable because not every image needs the same quality rule.

Record Every Output#

A single source may create several outputs:

{
  "source": "images/originals/homepage-hero.jpg",
  "outputs": [
    {
      "path": "images/optimized/homepage-hero-640.webp",
      "format": "webp",
      "width": 640
    },
    {
      "path": "images/optimized/homepage-hero-1280.webp",
      "format": "webp",
      "width": 1280
    }
  ]
}

This makes responsive image sets easier to audit. If one expected width is missing, the manifest can reveal the gap before a broken srcset reaches production.

For each output, include enough data to verify the relationship:

{
  "path": "images/optimized/homepage-hero-1280.webp",
  "format": "webp",
  "width": 1280,
  "bytes": 133120,
  "generatedFrom": "images/originals/homepage-hero.jpg",
  "status": "success"
}

Do not store only homepage-hero.webp. A final filename without source, size, format, and status does not support rollback or review.

Include Conversion Settings#

The manifest should also record settings that affect output:

  • format
  • quality
  • resize width
  • lossless or lossy mode
  • tool name and version when useful
  • date generated

Quality numbers are only meaningful with context. A record that says quality: 82 is much more useful when it also says the asset type, dimensions, and format.

Include the command and tool evidence:

{
  "tool": {
    "name": "getwebp",
    "version": "recorded-from-version-event",
    "command": "npx -y getwebp ./images/originals -o ./images/optimized --recursive --format webp --quality 82 --json"
  },
  "settings": {
    "format": "webp",
    "quality": 82,
    "qualityMode": "fixed",
    "recursive": true
  }
}

The GetWebP CLI command reference documents the relevant flags, including --output, --recursive, --format, --quality, --dry-run, --skip-existing, and --json. The JSON output reference documents the version preamble and per-file fields such as outputPath, originalSize, newSize, savedRatio, quality, qualityMode, and status.

Track Review Status#

Mechanical generation is not the same as approval. Add a review field:

{
  "review": {
    "status": "approved",
    "reviewer": "Design",
    "notes": "Checked homepage desktop and mobile hero."
  }
}

For rejected outputs, store the reason. This turns failed tests into useful evidence instead of forgotten artifacts.

Use constrained review states:

StateMeaning
pendingGenerated but not yet checked in the page or component
approvedCan be shipped
retryNeeds a new setting, size, crop, or format
keep_originalGenerated output is not acceptable
remove_from_pageBetter fix is to stop loading the image

Store the reason in plain language:

{
  "review": {
    "status": "retry",
    "reviewer": "Design",
    "notes": "Dashboard labels are soft at mobile content width."
  }
}

This prevents a manifest from becoming a false approval list.

Generate It From Structured Output#

Do not hand-type every byte count if your converter can produce structured output. For a GetWebP CLI run:

npx -y getwebp ./images/originals \
  -o ./images/optimized \
  --recursive \
  --format webp \
  --quality 82 \
  --json > ./reports/conversion.ndjson

Then parse the completed event:

jq -r 'select(.type == "convert.completed") | .data.results[] | [.status, .file, (.outputPath // ""), (.originalSize // ""), (.newSize // ""), (.savedRatio // ""), (.quality // ""), (.qualityMode // ""), (.error // "")] | @tsv' ./reports/conversion.ndjson > ./reports/conversion-results.tsv

The raw NDJSON remains the audit record. The manifest can be generated from it and enriched with review status, page usage, and source hashes.

For agent workflows, the GetWebP MCP server exposes convert_images. Its manifest_path parameter writes a JSON manifest with SHA-256 fingerprints for successful conversions, and the response includes manifest: { path, entries, generated_at } when a manifest is written. Use that when an agent is responsible for a local conversion pass.

Use the Manifest in CI#

CI can use the manifest to check that expected files exist and that source changes have matching outputs. It can also upload the manifest as an artifact for review.

Useful CI checks include:

  • every manifest output exists
  • no generated output is missing a source
  • changed source files have updated outputs
  • failed conversion events are linked to manifest entries
  • responsive image families are complete

GitHub's Actions documentation is useful when adding manifest checks to CI. Google's WebP documentation provides format background for WebP outputs.

Add explicit gates:

CI checkFailure meaning
Source hash changed but output hash did notSource was updated without regeneration
Output exists but review is not approvedMechanical output is being shipped without human approval
Manifest references absolute pathBuild is not portable
status: "error" appears in conversion reportPartial conversion needs triage
savedRatio is negative and output is approvedReviewer must justify why a larger file is acceptable
Responsive family is missing a widthsrcset may request a missing or oversized file

The GetWebP LLM context document helps CI decide whether to block immediately or parse partial results. Exit 3, for example, means at least one file failed while others succeeded, so the manifest should not pretend the batch is complete. Exit 2 is a usage error, which should be fixed at the command level before manifest data is trusted.

Keep It Small Enough to Maintain#

A manifest should help the workflow, not become a second database nobody trusts. For small projects, a JSON file in the repository may be enough. For large CMS or ecommerce systems, the manifest may be generated by the build or stored with asset records.

The important rule is that the manifest should be regenerated or updated by the same workflow that creates outputs. A stale manifest is worse than no manifest because it gives false confidence.

Start with a minimal schema:

{
  "schemaVersion": 1,
  "generatedAt": "2025-11-21T00:00:00.000Z",
  "tool": {},
  "entries": []
}

Add fields only when they support a decision: regeneration, review, CI gating, page delivery, or rollback. Do not turn the manifest into a content-management system unless the product already needs one.

Avoid Common Manifest Mistakes#

The manifest should not list only final filenames. It should explain how those files relate to source assets and settings. It should also avoid storing absolute machine-specific paths such as /Users/alex/Desktop/export, because those paths will not work for another teammate or CI runner.

Common mistakes include:

  • missing source references
  • outputs without dimensions
  • no review status
  • no record of quality settings
  • stale entries for deleted files
  • paths that only work on one machine

Review the manifest as part of the migration, not as an afterthought.

Also avoid mixing goals:

MistakeBetter rule
Counting unapproved outputs as winsCount only approved outputs in performance summaries
Treating storage cleanup as page speedSeparate storage-only records from page-loaded assets
Re-encoding generated WebP as a sourcePreserve original source or approved working copy
Omitting page usageAdd page or component references for user-facing performance claims
Hiding failed conversionsKeep errors and rejected outputs in the audit trail

Those mistakes are common in low-quality optimization reports because they make the numbers look better than the actual publishing state.

Use It for Rollback#

When a migration fails, the manifest helps answer:

  • which outputs were created?
  • which source files are involved?
  • which pages or components reference them?
  • can the outputs be regenerated?
  • which files should be removed?

That makes rollback calmer. The team can remove generated files or restore references based on a record instead of a folder search.

A rollback-ready manifest entry can include page usage:

{
  "source": { "path": "images/originals/homepage-hero.jpg", "sha256": "sha256:..." },
  "outputs": [{ "path": "images/optimized/homepage-hero.webp", "format": "webp", "status": "success" }],
  "usedBy": ["/", "components/HomeHero"],
  "review": { "status": "approved", "notes": "Checked desktop and mobile LCP slot." },
  "rollback": { "remove": ["images/optimized/homepage-hero.webp"], "restoreReference": "images/originals/homepage-hero.jpg" }
}

That entry tells the release owner which generated file to remove and which page or component to inspect after rollback.

An image manifest is not complicated. It is a map from source to output, with settings and review status attached. That map makes image optimization easier to repeat, debug, audit, and explain.

Jack avatar

Jack

GetWebP Editor

Jack writes GetWebP guides about local-first image conversion, WebP workflows, browser compatibility, and practical performance checks for teams that publish images on the web.