Vysk
Image optimization for the command line, with a Rust core.
What it is
Vysk is a developer tool for making website images smaller. It runs as an npm package, not a hosted service. It scans your project, converts PNG and JPG files to WebP, and shows a report of what it saved. It never touches your originals, and it skips any output that isn't actually smaller.
Under the hood
What I built
- Phase 1, the CLI. Scans
public/, compresses and converts images beside the originals, and prints an optimization report. - Phase 2, builds. A hash-based cache so unchanged images are never reprocessed, a config file, and a documented
prebuildpattern. - Phase 3, rewriting references. A
rewritecommand that finds image references in your code, shows the full plan, and only writes after an explicit yes. It backs up originals first, refuses to run on a dirty git tree, and has 25 passing tests. - Safety. A
--dry-runthat runs the whole pipeline and writes nothing.
Results
Tested on real client projects. On one Next.js project, a 26.96 MB PNG became 1.17 MB. Running it again on all 14 images finished instantly from the cache, with the same totals.
What broke
WebP has a size limit. WebP can't encode images larger than 16,383 pixels on a side, so huge images were skipped. Now they fall back to AVIF through the ravif crate. That pulled a Phase 3 feature forward, and it added nasm as a build requirement.
Git detection that was too literal. The safety check looked for a .git folder in the project root only, so it refused to run on a project nested inside a bigger repository. I replaced it with git status --porcelain and let git find the repository itself.
Engineering decisions
I used Rust as the core engine instead of reaching for sharp. Part of the reason is that I wanted this project to be a real Rust project. Connecting it through napi-rs means people install one package and never see the toolchain.
Where it stands
Not published to npm yet. I haven't tested it on Windows, and I'd like people to install it and tell me what breaks.
What it runs on
TypeScript, Node.js, Rust, napi-rs, ravif.