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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@yankeeinlondon/image-opt

v0.3.1

Published

Optimize your source images for the web

Downloads

794

Readme

Image Opt

A CLI and Vite plugin which converts image assets into a highly optimized set of images for use on the web.

Installation

# install globally
pnpm install -g @yankeeinlondon/image-opt

# install locally to repo
pnpm install -D @yankeeinlondon/image-opt

Source to Destination Mapping

Rather than just perform a 1:1 mapping with some compression or possibly image format conversion, we instead convert a source image into many images with the expectation that the user will want to leverage modern techniques to allow the runtime environment to choose the best asset for a given client.

CLI Usage

Overview

# help menu
io --help

# interactive configuration
io -i

# convert a single file (no config needed)
io public/foobar.jpg --to dist
# single file with explicit sizes
io public/foobar.jpg --to dist --sizes=1024,640,320

# convert using configuration
io
# break any cached conversions
io -f

# watch mode
io --watch
# or
io -w

Modes

There are two primary modes of operation for the io CLI:

  1. One Off
  2. Configure and Repeat

The second use-case is really the primary goal for this repo but you can see above in the CLI overview that one-off conversions are also an option should you need them.

Configure and Repeat

You can either configure file yourself (which should reside at .img-opt.json in the root of your repo), or run io -i to configure it interactively. For most people we'd just recommend the interactive option to start but once you see the configuration file it's sometimes easier to make any future modifications directly on the configuration file.

Configuration Structure

Here's a rough approximation of the configuration structure your JSON file will take on but refer to the ConfigFile type in the repo for an always up-to-date articulation of this.

type InputFormat = "jpg" | "png" | "webp" | "avif" | "gif" | "tiff";
type OutputFormat = "jpg" | "png" | "webp" | "avif" | "gif" | "heif";

type SourceConfig = {
	/** a glob pattern used to identify which files are part of this set of images */
	glob: string;
	/** the sizes these images will be resized to (in addition to retaining full resolution) */
	sizes?: number[];
	formats?: OutputFormat[];
	/** whether metadata should be preserved or stripped */
	withMetadata?: boolean;
	/** the directory to output these files into */
	outputDir?: string;
	quality?: {
		jpg?: { ... };
		webp?: { ... };
		avif?: { ... };
		gif?: { ... };
		heif?: { ... };
	}
}

type ConfigFile = {
	// default values
	defaultSizes: number[];
	defaultFormats: InputFormat[];
	defaultMeta: boolean;
	defaultOutputDir: string;
	qualityDefaults: {
		jpg: { ... };
		webp: { ... };
		avif: { ... };
		gif: { ... };
		heif: { ... };
	}
	// configuration per set of source images
	sources: SourceConfig[];
}

Reviewing the structure you can see that:

  • the default properties are likely to be highly reusable across different source groups
    • the defaults we provide when using the interactive configuration may be all you ever need/use
  • each source group defines a glob pattern to identify which files it bring in; all other properties are optional

Caching

Because each source image will be converted to several destination images there is value in making sure we only convert source images which have changed. Therefore, by default, when you run io it will use a cache file located at .img-cache.json to ensure that only the required work is done to reach the end state. Should you ever want to break the cache then just add the --force or -f flag to the CLI and it will will blow away the existing cache, convert everything and rebuild a cache from this work.

The cache mechanics are rather simple, it simply looks at the file's last modified date and file size and if they've changed it assume the image has changed. That means if you touch a file you want to be sure to be [re-]converted then that should work.

Vite Plugin

This will eventually be made into a Vite plugin but currently just stabilizing the CLI use cases.

Frontend Component

In addition to providing a CLI for image optimization and a ViteJS plugin for auto image generation as part of your build pipeline, it also provides a frontend component to view your optimized images.

Installation

This frontend component comes in three flavors:

  1. VueJS Component

    import ImageOpt from "@yankeeinlondon/image-opt/vue";

    A traditional VueJS single file component.

  2. VueJS Component (using the new Vapor Mode)

    import ImageOpt from "@yankeeinlondon/image-opt/vapor";

    A super-small and fast variant using VueJS's soon to be released "vapor mode". This component can be safely used with traditional VueJS components as well as other frameworks.

    Because it does not use any of the ShadowDOM dependencies it's footprint is very small.

  3. Custom Element

    import ImageOpt from "@yankeeinlondon/image-opt/custom-element";

    Uses the browser's built in ability to leverage "custom components".

Functional Overview

Regardless of which variant you choose, the aim is to have the functionality precisely the same across the three variants.