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

@aleburato/primeval

v0.1.1

Published

TypeScript-first Node package for primeval image approximation.

Readme

primeval

primeval turns photos and artwork into stylized reconstructions built from simple geometric shapes.

Give it an input image and it searches for a layered approximation you can export as PNG, JPG, GIF, or clean SVG output.

Inspired by Michael Fogleman's original primitive, this repository is an independent Rust implementation with a reusable core library (primeval-core), a CLI (primeval-cli), and an ESM-only Node package (@aleburato/primeval).

Highlights

  • Fast hill-climbing search with multi-threaded worker contexts
  • Nine shape modes in the CLI: mixed (any), triangle, rectangle, ellipse, circle, rotated rectangle, quadratic curve, rotated ellipse, and polygon
  • Small working-resolution optimization with high-resolution output replay
  • Vector export via SVG, plus raster output for PNG, JPG, and animated GIFs

Install

Node package

npm install @aleburato/primeval

Prebuilt native addons are provided for macOS (arm64, x64), Linux (arm64, x64), and Windows (x64). Node 20+ is required.

CLI from source

Clone the repository and build the release binary:

git clone [email protected]:aleburato/primeval.git
cd primeval
cargo build --release

Or install the CLI directly:

cargo install --path crates/primeval-cli

Quick Start

Run the CLI against one of the bundled README originals:

./target/release/primeval-cli run \
  docs/readme/originals/monalisa.jpg \
  --output output/monalisa.png \
  --emit png,svg \
  --count 1000

Useful options:

  • --shape any|triangle|rectangle|ellipse|circle|rotated-rectangle|quadratic|rotated-ellipse|polygon with any as the default
  • --count <N> number of optimization steps (default 100)
  • --alpha <N>|auto shape opacity, 1..255 or auto (default 128)
  • --resize-input <N> working resolution (default 256)
  • --output-size <N> final replay resolution (default 1024)
  • --repeat <N> extra candidates per step (default 0)
  • --threads <N> worker thread count (defaults to available cores)
  • --seed <N> for deterministic output
  • --emit png,jpg,svg,gif one or more output formats

See the full CLI help with:

./target/release/primeval-cli run --help

Node Package

The npm package is ESM-only and targets Node 20+.

import { approximate } from "@aleburato/primeval";
import { readFile } from "node:fs/promises";

const input = await readFile("docs/readme/originals/monalisa.jpg");

const result = await approximate({
  input: { kind: "bytes", data: input },
  output: "svg",
  render: {
    count: 300,
    shape: "any",
  },
});

console.log(result.format, result.width, result.height);
console.log(result.data.slice(0, 32));

Convert results to a data URI:

import { approximate, toDataUri } from "@aleburato/primeval";
import { readFile } from "node:fs/promises";

const input = await readFile("docs/readme/originals/monalisa.jpg");
const result = await approximate({
  input: { kind: "bytes", data: input },
  output: "png",
  render: { count: 200 },
});

const uri = toDataUri(result);
console.log(uri.slice(0, 64));

Abort long renders with AbortSignal:

import { AbortError, approximate } from "@aleburato/primeval";
import { readFile } from "node:fs/promises";

const controller = new AbortController();
const input = await readFile("docs/readme/originals/monalisa.jpg");

try {
  const promise = approximate({
    input: { kind: "bytes", data: input },
    output: "svg",
    render: { count: 1000 },
    execution: {
      signal: controller.signal,
      onProgress(info) {
        if (info.step === 10) {
          controller.abort();
        }
      },
    },
  });

  await promise;
} catch (error) {
  if (error instanceof AbortError) {
    console.log("render aborted");
  } else {
    throw error;
  }
}

Package notes:

  • Default render options match the Rust render facade and CLI defaults: count: 100, shape: "any", alpha: 128, repeat: 0, background: "auto", resizeInput: 256, and outputSize: 1024.
  • approximate() returns exactly one output format per call: svg, png, jpg, or gif.
  • The default shape is any (mixed); all nine CLI shape modes are available.
  • Errors are mapped to ValidationError, NotFoundError, and AbortError — use instanceof to distinguish them.
  • For SVG results, data is a string; for raster results, data is a Buffer.

Progression Gallery

Each table below shows one original image, with shape modes in rows and step counts in columns. Every preview is a JPEG thumbnail that links to the generated SVG.

Mona Lisa

American Gothic

Fiume Po (M.Kenna)

Spongebob

Benchmarks

Using docs/readme/originals/americangothic.jpg as the input image, 500 steps per run, and all nine shape modes (any, triangle, rectangle, ellipse, circle, rotated rectangle, quadratic, rotated ellipse, polygon), the Rust CLI completed the full matrix in 1m 18s versus 2m 41s for the original Go CLI from fogleman/primitive.

That works out to a 2.06x speedup overall (51.5% less total time). On this run, Rust was faster in all 9 modes and delivered 4.0% lower average RMSE overall (15.97 vs 16.63). It also produced lower RMSE in 7 of the 9 individual modes.

| Shape | Rust time | Go time | Speedup | Rust RMSE | Go RMSE | | --- | ---: | ---: | ---: | ---: | ---: | | Mixed | 7.6s | 14.6s | 1.9x | 12.3 | 13.6 | | Triangle | 4.0s | 9.1s | 2.3x | 14.4 | 14.6 | | Rectangle | 2.5s | 7.1s | 2.8x | 15.2 | 14.6 | | Ellipse | 5.6s | 18.2s | 3.3x | 12.3 | 12.6 | | Circle | 7.6s | 21.7s | 2.9x | 14.2 | 14.5 | | Rotated rectangle | 4.5s | 9.6s | 2.1x | 12.8 | 14.1 | | Quadratic | 6.1s | 23.2s | 3.8x | 39.5 | 38.3 | | Rotated ellipse | 24.8s | 39.4s | 1.6x | 11.8 | 13.8 | | Polygon | 15.2s | 17.7s | 1.2x | 11.1 | 13.7 |

Lower RMSE is better. Times are from a single local benchmark run and will vary by machine. The upstream Go CLI does not expose a fixed seed flag, so the quality comparison reflects one representative run rather than a deterministic seed-matched replay.

Usage in the Wild

Real projects using primeval beyond demos and benchmarks:

  • nudaluce.com (NSFW) — my photography website uses primeval-generated SVGs as LQIPs (low-quality image placeholders), replacing the more typical blurred-image placeholder technique with geometric previews.

Want your project listed here? Send an email to [email protected] with the URL of the related resource.

Development

Run the standard quality gates from the repository root:

# Rust
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test

# Node / package
npm run typecheck
npm test
npm run test:tooling
npm pack --dry-run

npm test builds the TypeScript wrapper and native addon before running the full package test suite, including the native-path tests.

For local development when you want the native build step by itself:

npm ci
npm run test:native:build
npm run test:native

The comparison harness lives at scripts/benchmark.py. It can compare any two compatible binaries and writes reports to output/.

License

Released under the MIT License.