Skip to main content
The image pipeline is a set of open source Node.js scripts that solve a common problem in vibe-coded apps: images served from external URLs (builder CDNs, Unsplash, etc.) that you don’t control. This pipeline downloads those images, compresses them to WebP using Sharp, and replaces all URL references in your source code with local paths — dramatically improving page load times and eliminating dependency on third-party image hosts.
These scripts are open source and reusable in any Node.js project — not just Nometria deployments.

What it does

Three steps, run in sequence:
External image URLs in your code

        │ download-images.js

  public/images/*.png, *.jpg

        │ compress-images.js

  public/images/*.webp  (originals deleted)

        │ replace-image-urls.js

  Source code updated to use /images/*.webp

Installation

Install from npm:
npm install --save-dev @nometria-ai/img-opt sharp
Available on npm as @nometria-ai/img-opt · Source on GitHub
Or copy files into your project’s scripts/ folder manually:
  • scripts/download-images.js
  • scripts/compress-images.js
  • scripts/replace-image-urls.js
  • scripts/images-download-compress-replace.js (orchestrator)
  • scripts/lib/get-config.js
  • scripts/image-assets.config.js (edit this)
If using the npm package, Sharp is listed as a peer dependency — install it alongside:
pnpm add -D @nometria-ai/img-opt sharp
# or
npm install --save-dev @nometria-ai/img-opt sharp
Add scripts to package.json:
{
  "scripts": {
    "images": "node scripts/images-download-compress-replace.js",
    "images:download": "node scripts/download-images.js",
    "images:compress": "node scripts/compress-images.js",
    "images:replace-urls": "node scripts/replace-image-urls.js"
  }
}

Configuration

Edit scripts/image-assets.config.js:
export default {
  // Where to save downloaded images
  imagesDir: 'public/images',

  // External image URLs to download
  // Supports Unsplash, any direct image URL
  sources: [
    'https://images.unsplash.com/photo-1518770660439-4636190af475?w=1200',
    'https://images.unsplash.com/photo-1555099962-4199c345e5dd?w=1200',
    // ... add all external image URLs your app uses
  ],

  // Directories to search when replacing URLs
  replaceInDirs: ['src', 'public'],

  // Compression options
  compress: {
    quality: 82,          // WebP quality (0-100). 82 is a good balance.
    removeOriginals: true // Delete PNG/JPG after converting to WebP
  }
};

Usage

# Run all three steps at once (recommended)
pnpm run images

# Or run steps individually
pnpm run images:download    # Step 1: download externals to public/images/
pnpm run images:compress    # Step 2: convert to WebP, delete originals
pnpm run images:replace-urls # Step 3: update URLs in source code

Example output

$ pnpm run images

Downloading images...
  https://images.unsplash.com/photo-1518770... public/images/photo-1518770660439.jpg (284 KB)
  https://images.unsplash.com/photo-1555099... public/images/photo-1555099962.jpg (198 KB)
  Downloaded 2 images.

Compressing images...
  photo-1518770660439.jpg photo-1518770660439.webp... OK (41.2 KB)
  photo-1555099962.jpg photo-1555099962.webp...    OK (28.7 KB)
  Done. WebP files in public/images/

Replacing URLs in source...
  src/pages/Home.jsx: 3 replacements
  src/components/Hero.jsx: 1 replacement
  Done. 4 replacements across 2 files.
Before (slow — image served from Unsplash CDN):
<img src="https://images.unsplash.com/photo-1518770660439-4636190af475?w=1200" />
After (fast — local WebP, served from your own host):
<img src="/images/photo-1518770660439.webp" />

Why WebP?

WebP provides 25–35% smaller file sizes compared to JPEG at equivalent visual quality, and 25–50% smaller than PNG for images with transparency. All modern browsers support WebP. The default quality setting of 82 is a good balance — noticeably smaller than JPEG at 90, with no visible quality difference at screen resolution.

Custom config path

If you want to keep the config outside scripts/:
IMAGE_ASSETS_CONFIG=./my-config.js pnpm run images

Integrating into your deploy workflow

Add image optimization as a pre-build step so it runs before every deployment:
{
  "scripts": {
    "prebuild": "pnpm run images",
    "build": "vite build"
  }
}
Or run it manually when you add new images to your project, rather than on every build (since images don’t change often).

Source files

The package is available on npm and the source is on GitHub. The same scripts are embedded as templates in Nometria-generated projects.