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

@nometria-ai/img-opt

v2.1.1

Published

Auto-scan, download, compress (WebP + WebM), and rewrite image & video URLs. Zero config.

Downloads

569

Readme

img-opt

npm version npm downloads Node.js License: MIT

Auto-scan your codebase for external images & videos, compress to WebP/WebM, rewrite all URLs. Zero config.

Eliminates external media dependencies, cuts image payload by 60-80%, compresses videos to WebM, and updates every URL reference in your source automatically. Works with Vite, Next.js, Astro, Vue, and Svelte projects.


Quick start

# Install
npm install --save-dev @nometria-ai/img-opt sharp

# Run — that's it. No config file needed.
npx img-opt

img-opt auto-scans your src/ directory for external image and video URLs, downloads them, compresses images to WebP and videos to WebM, then rewrites every URL reference.


What's new in v2.0

  • Auto-scan — no more manual sources config. img-opt discovers external URLs automatically.
  • Video support — download and compress videos to WebM via ffmpeg.
  • Zero-config — works without image-assets.config.js. Sensible defaults for all settings.

Install

# As a dev dependency (recommended)
npm install --save-dev @nometria-ai/img-opt sharp

# For video compression, install ffmpeg:
# macOS:   brew install ffmpeg
# Ubuntu:  sudo apt install ffmpeg
# Windows: choco install ffmpeg

sharp is a peer dependency for image compression. ffmpeg is a system dependency for video compression. Both are optional — the pipeline skips steps gracefully if they're missing.


Commands

npx img-opt                # full pipeline (scan → download → compress → replace)
npx img-opt scan           # discover external image/video URLs (dry-run)
npx img-opt download       # fetch external images + videos
npx img-opt compress       # convert PNG/JPG → WebP via Sharp
npx img-opt video          # convert MP4/MOV → WebM via ffmpeg
npx img-opt replace        # rewrite external URLs in source files

Add to package.json scripts:

{
  "scripts": {
    "optimize": "img-opt",
    "optimize:scan": "img-opt scan"
  }
}

How it works

Auto-scan (new in v2.0)

When no sources are configured, img-opt scans your codebase and detects:

  • <img src="https://..."> and <Image src="..."> (React, Next.js)
  • <video src="...">, <source src="...">, poster="..."
  • CSS url(https://...)
  • Markdown ![alt](https://...)
  • String literals containing image/video URLs (.png, .jpg, .mp4, etc.)
  • srcset attribute entries

Run npx img-opt scan to preview what will be found before downloading.

Local asset compression

Even without external URLs, img-opt compresses local uncompressed images and videos already in your project. It scans src/, public/, and any configured replaceInDirs for .png, .jpg, .mp4, etc., compresses them in place, and rewrites all references.

This means dropping a .png into src/assets/ and running npx img-opt will automatically convert it to .webp and update your imports. Set compressLocal: false to disable.

Ignore patterns

Use the ignore config to skip certain URLs or file paths:

export default {
  ignore: [
    'cdn.dynamic-api.com',        // skip any URL containing this string
    '/user-avatar-\\d+/',         // regex: skip dynamic avatar URLs
    'src/assets/brand-logo',      // skip a specific local file
  ],
};

Ignored items are excluded from scanning, downloading, and compression.

Pipeline

  1. Scan — auto-discovers external image and video URLs in your source files
  2. Download — fetches each URL (follows redirects), saves to public/images/ and public/videos/
  3. Compress images — converts PNG/JPG to WebP at configured quality using Sharp
  4. Compress videos — converts MP4/MOV/AVI to WebM using ffmpeg (VP9 + Opus)
  5. Replace — rewrites all URLs in source files (.png.webp, .mp4.webm, external URLs → local paths)

Configuration (optional)

Create image-assets.config.js in your project root to override defaults:

export default {
  autoScan: true,                    // scan codebase for URLs (default: true)
  compressLocal: true,               // compress local uncompressed assets too (default: true)
  imagesDir: 'public/images',       // where to save downloaded images
  videosDir: 'public/videos',       // where to save downloaded videos
  replaceInDirs: ['src'],           // directories to scan
  compress: {
    format: 'webp',
    quality: 82,
    removeOriginals: true,
  },
  videoCompress: {
    format: 'webm',
    quality: 'good',                // 'fast' | 'good' | 'best'
    maxWidth: 1920,
    removeOriginals: true,
  },
  // Skip certain URLs or file paths
  ignore: [
    // 'cdn.dynamic-api.com',       // substring match
    // '/avatar-\\d+/',             // regex match
  ],
  // Manual sources (optional — auto-scanned if empty)
  sources: [],
  videoSources: [],
};

Configuration options

| Option | Type | Default | Description | |--------|------|---------|-------------| | autoScan | boolean | true | Auto-discover external URLs when sources is empty | | compressLocal | boolean | true | Also compress local uncompressed images/videos in the project | | ignore | string[] | [] | Patterns to skip (substring or /regex/). Applied to URLs and file paths | | imagesDir | string | 'public/images' | Directory where images are saved | | videosDir | string | 'public/videos' | Directory where videos are saved | | replaceInDirs | string[] | ['src'] | Directories scanned for URL replacement | | replaceExtensions | string[] | see below | File extensions to scan | | compress.format | 'webp' | 'jpeg' | 'png' | 'webp' | Output image format | | compress.quality | number | 82 | Image compression quality (1-100) | | compress.removeOriginals | boolean | true | Delete source files after converting | | videoCompress.format | string | 'webm' | Output video format | | videoCompress.quality | 'fast' | 'good' | 'best' | 'good' | Video quality preset | | videoCompress.maxWidth | number | 1920 | Scale down videos wider than this | | videoCompress.removeOriginals | boolean | true | Delete source video after converting | | sources | Array | [] | Manual { url, file } list (auto-scanned if empty) | | videoSources | Array | [] | Manual { url, file } list (auto-scanned if empty) |

Default replaceExtensions: .js, .jsx, .ts, .tsx, .html, .vue, .svelte, .md, .mdx, .css, .astro


Supported frameworks

Works with any framework that serves a public/ directory:

| Framework | Config imagesDir | Config replaceInDirs | |-----------|-------------------|----------------------| | Vite / Vue | public/images | ['src'] | | Next.js | public/images | ['app', 'pages', 'components'] | | Astro | public/images | ['src'] | | Svelte | public/images | ['src'] | | Plain HTML | images | ['.'] |


CI integration

Run as part of your build:

# .github/workflows/build.yml
- name: Optimize assets
  run: npx img-opt

Typical results

| Metric | Before | After | |--------|--------|-------| | External requests at load | 8-12 | 0 | | Image payload | 2.4 MB | 480 KB | | Video payload | 15 MB | 4 MB | | Largest Contentful Paint | 3.1 s | 1.2 s |


Contributing

PRs welcome. Run tests with npm test.


License

MIT - Nometria