ipx
ipx copied to clipboard
Support squoosh
squoosh is a wasm alternative to sharp. While sharp is much faster and supporting modern formats, it has its own downsides:
- NodeJS dependency. Cannot be used in environments like Deno or Cloudflare workers
- Native dependency. This reduces the portability of the library. Both bundle distribution and target-machine (if there is no pre-built version for a specific node version, installation requires building with node-gyp) (example https://github.com/nuxt/image/issues/204)
We can keep sharp as an opt-in dependency and install/use squoosh by default. This needs a refactor for handlers to create a shared interface. (as a result, we lose some existing features)
Note: squoosh api seems is not released on npm nor documented! We might use/redistribute http://npmjs.com/package/@squoosh/cli, inspire and inline source similar to https://github.com/vercel/next.js/pull/22253, or publish as squoosh.
Related: https://github.com/GoogleChromeLabs/squoosh/issues/934 / https://github.com/GoogleChromeLabs/squoosh/pull/1002 (PR depends on NodeJS API like worker_threads
therefore removing first point)
This looks like a cool idea! I expect that @squoosh/lib
will be released on npm in a few days, but it will only be an experimental release. It has a list of known issues, it has spotty documentation, and the API isn't finalised yet.
I would recommend keeping sharp as the default backend, but adding squoosh as an option and letting the end user choose which one to use. Then when the squoosh API hopefully one day becomes more stable, you can consider making it the default. But that's just my take, and I am not that familiar with this project :)
Awesome to see this. Just want to add that enabling squoosh here will also enable full compatibility inside of WebContainers (more info in the blog post / repo)
@pi0
I have used @squoosh/lib": "^0.3.1
to optimize my backend images
Usage
const fs = require('fs/promises');
const { ImagePool } = require('@squoosh/lib');
const { cpus } = require('os');
const imagePool = new ImagePool(cpus().length);
async function convert2WebpAndAvif(originalImage: Buffer) {
const image = imagePool.ingestImage(originalImage);
const encodeOptions = {
webp: {}, //empty object means using the default configuration
avif: {},
};
await image.encode(encodeOptions);
const [webp, avif] = await Promise.all([
image.encodedWith.webp,
image.encodedWith.avif,
]);
return {
webp,
avif,
};
}
// ==== Usage ==== //
const file = await fs.readFile('image.png');
const { webp, avif } = await convert2WebpAndAvif(imageBuffer);
await Promise.all([
fs.writeFile('image.webp', webp.binary),
fs.writeFile('image.avif', avif.binary),
]);
Caveats and Concerns
- When I used the latest version
0.4.0
,avif
format does not work, so I revert back to version0.3.1
. - The latest version (
0.4.0
) is 9 months old with no recent updates or bug fixes . - It needs nodejs
v.16.*
and doesn't work on the latestlts
nodejs version (v18.*
) - It takes a lot of time to convert images, which makes it unsuitable for converting images on demand (per API request), however, it can be used to process images in a work queue in the background and serve the optimized images when ready.
The Squoosh library has unfortunately been discontinued indefinetely. You can still use the WASM enc/-decoders directly from the Squoosh source code, but other than that you are out of luck.
Thankfully, you can instead use wasm-vips, which is a WASM implementation of the library that Sharp uses under the hood. In the future, we might even get a cross-platform version of sharp that uses wasm-vips.
Closing this and waiting for wasm support for sharp.
The Squoosh library has unfortunately been discontinued indefinetely
Do you have a link for that @atjn? Maybe you mean the "Project no longer maintained" notice on @squoosh/lib
?
Project no longer maintained
Unfortunately, due to a few people leaving the team, and staffing issues resulting from the current economic climate (ugh), this package is no longer actively maintained. I know that sucks, but there simply isn't the time & people to work on this. If anyone from the community wants to fork it, you have my blessing. The squoosh.app web app will continue to be supported and improved.

waiting for wasm support for sharp
Is this an ongoing project? Do you have a link for this @pi0 ?
Sharp support for WASM seems ongoing here: https://github.com/lovell/sharp/pull/3522
@karlhorky I am not entirely sure what you are asking for, but yes, the notice on @squoosh/lib is probably the most official communication available. I worked on @squoosh/lib, so I knew from talking to Jake that they were stopping work on it, and since it wasn't stable yet, that essentially killed the project for good.
Seems like landed! https://github.com/lovell/sharp/pull/3522#issuecomment-1805398977
Any plans to support it?
@brendonmatos See https://github.com/unjs/ipx/pull/190 ;)