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

pixelati

v0.1.1

Published

Turn any image into truecolor terminal art using half-block characters.

Readme

pixelati

Turn any image into truecolor terminal art. pixelati renders pictures into the terminal using half-block characters, so each character cell shows two stacked pixels at full 24-bit colour, with transparent areas left blank.

It works as both a command line tool and a small library, and it reads any format sharp can decode (PNG, JPEG, WebP, GIF, AVIF, TIFF, and more).

Install

As a CLI:

npm install -g pixelati
pixelati <image>

As a library:

npm install pixelati
import { renderToLines } from "pixelati";
const lines = await renderToLines("logo.png", { width: 56 });
console.log(lines.join("\n"));

This is an ESM-only package and needs Node 18 or newer.

Local development

pnpm install
pnpm build       # compiles to dist/
pnpm pixelati <image>   # run from source via tsx

Usage

pixelati <image> [options]

| Option | Description | |---|---| | -w, --width <n> | Output width in columns. Defaults to the terminal width, or 80 when piped. | | -H, --height <n> | Maximum height in rows. The image is scaled to fit within width × height, preserving aspect, so tall images stay inside the box. | | -t, --threshold <n> | Alpha cutoff from 0 to 255. Pixels at or below it are treated as transparent. Default 128. | | -b, --background <hex> | Composite the image onto this colour instead of leaving transparent gaps (for example #1e1e2e). | | -T, --trim | Crop uniform or transparent borders before scaling, so a subject centred in a large canvas (like a sprite) fills the frame instead of rendering tiny. | | -o, --output <file> | Write the art to a file instead of printing it. | | -h, --help | Show help. |

Examples

pixelati logo.png                  # render at terminal width
pixelati photo.jpg -w 60           # render 60 columns wide
pixelati icon.png -b "#000000"     # composite onto black, no transparency
pixelati banner.png -w 100 -o banner.ans   # save the escapes to a file

The height is derived from the width to preserve the image's aspect ratio, so you only ever set the width.

Library

import { renderToLines, renderToString } from "pixelati";

// Array of ANSI strings, one per text row.
const lines = await renderToLines("logo.png", { width: 56 });
console.log(lines.join("\n"));

// Or the whole thing as one string.
const art = await renderToString("logo.png", { width: 56, background: "#101018" });

renderToLines and renderToString accept a file path or a Buffer, plus the same options as the CLI (width, threshold, background). Returning lines as an array is handy for baking the art into a generated source file, so a program can ship the rendered banner without any image dependency at runtime.

How it works

The short version: a terminal cell is about twice as tall as it is wide, and ANSI lets you set a foreground and a background colour per cell independently. The (upper half block) paints the top half of the cell with the foreground while the background shows through the bottom half, so one character carries two vertically stacked pixels. That doubles vertical resolution, and truecolor escapes give each pixel any of 16 million colours. Transparent pixels become blanks so the terminal background shows through.

For the full walkthrough (downscaling, the transparency cases, aspect ratio, and how to verify the output visually) see docs/how-it-works.md.

Requirements

Node.js 18 or newer, and a terminal with truecolor support (most modern terminals: iTerm2, the macOS Terminal in recent versions, Windows Terminal, kitty, Alacritty, WezTerm, and others).

License

MIT