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

@pinkpixel/pixelpop

v1.0.1

Published

A terminal utility for displaying and animating images, GIFs and photo sequences with ANSI color support

Readme

npm version License: Apache-2.0 Node.js Version TypeScript Downloads GitHub Stars

Pixelpop is a sophisticated terminal utility library that brings visual content to command-line applications. With intelligent terminal detection and multiple rendering strategies, it ensures your images look great across different terminal environments.

🎬 Demos

✨ Features

  • 🖼️ Multi-format Support - Display JPEG, PNG, GIF, and more
  • 🎬 GIF Animation - Smooth animated GIF playback with frame rate control
  • 🎯 Smart Terminal Detection - Automatically adapts to your terminal's capabilities
  • 📐 Flexible Sizing - Percentage-based dimensions with aspect ratio preservation
  • 🌈 Universal Compatibility - Works in iTerm2, Kitty, WezTerm, and standard terminals
  • High Performance - Optimized rendering with intelligent fallbacks
  • 🔧 TypeScript Ready - Full type definitions included

🚀 Quick Start

Installation

# Using npm
npm install @pinkpixel/pixelpop

# Using yarn  
yarn add @pinkpixel/pixelpop

# Using pnpm
pnpm add @pinkpixel/pixelpop

Note: @pinkpixel/pixelpop is ESM-only ("type": "module"). Use ESM in your project, or use dynamic import() from CommonJS if needed.

Basic Usage

import pixelPop from '@pinkpixel/pixelpop';

// Display a static image
const output = await pixelPop.file('./my-image.jpg', {
  width: '50%'
});
console.log(output);

// Play an animated GIF
const stop = await pixelPop.gifFile('./my-animation.gif', {
  width: '80%',
  maximumFrameRate: 24
});

// Stop the animation after 5 seconds
setTimeout(stop, 5000);

📖 API Reference

Static Image Methods

pixelPop.file(filePath, options?)

Display an image from a file path.

await pixelPop.file('./image.jpg', {
  width: '60%',
  height: 20,
  preserveAspectRatio: true
});

pixelPop.buffer(buffer, options?)

Display an image from a buffer.

const imageBuffer = fs.readFileSync('./image.jpg');
await pixelPop.buffer(imageBuffer, { width: '50%' });

Animated GIF Methods

pixelPop.gifFile(filePath, options?)

Play an animated GIF from a file path. Returns a function to stop the animation.

const stop = await pixelPop.gifFile('./animation.gif', {
  width: '75%',
  maximumFrameRate: 30
});

pixelPop.gifBuffer(buffer, options?)

Play an animated GIF from a buffer. Returns a function to stop the animation.

const gifBuffer = fs.readFileSync('./animation.gif');
const stop = await pixelPop.gifBuffer(gifBuffer, {
  maximumFrameRate: 15
});

Options

RenderOptions

interface RenderOptions {
  width?: DimensionValue;        // number or percentage string like '50%'
  height?: DimensionValue;       // number or percentage string like '50%'  
  preserveAspectRatio?: boolean; // default: true
}

GifOptions

interface GifOptions extends RenderOptions {
  maximumFrameRate?: number;  // default: 30
  renderFrame?: RenderFrame;  // custom frame renderer
}

DimensionValue

type DimensionValue = number | `${number}%`;

🎯 Examples

Responsive Image Display

import pixelPop from '@pinkpixel/pixelpop';

// Adapt to terminal size
await pixelPop.file('./hero-image.jpg', {
  width: '100%',
  preserveAspectRatio: true
});

Controlled GIF Animation

import pixelPop from '@pinkpixel/pixelpop';

const stop = await pixelPop.gifFile('./loading.gif', {
  width: '25%',
  maximumFrameRate: 20
});

// Stop after process completes
await someAsyncOperation();
stop();

Custom Frame Rendering

import pixelPop from '@pinkpixel/pixelpop';
import logUpdate from 'log-update';

const customRenderer = (frame: string) => {
  logUpdate(`\n🎬 Animation Frame:\n${frame}`);
};

customRenderer.done = () => {
  logUpdate.done();
  console.log('Animation complete!');
};

await pixelPop.gifFile('./demo.gif', {
  renderFrame: customRenderer,
  maximumFrameRate: 24
});

Buffer Processing

import pixelPop from '@pinkpixel/pixelpop';
import { promises as fs } from 'fs';

const imageBuffer = await fs.readFile('./screenshot.png');
const output = await pixelPop.buffer(imageBuffer, {
  width: 80,
  height: '50%'
});

console.log(output);

🏗️ How It Works

Pixelpop uses a sophisticated multi-strategy rendering approach:

1. Terminal Detection

Automatically detects your terminal's capabilities by checking environment variables:

  • TERM_PROGRAM (iTerm2, WezTerm, etc.)
  • TERM (xterm-kitty, etc.)
  • KITTY_WINDOW_ID and KONSOLE_VERSION

2. Rendering Strategies

🏆 Native Support (iTerm2, etc.)

Uses term-img for terminals with built-in image protocols.

Kitty Protocol (Kitty, WezTerm, Konsole)

Direct image rendering using Kitty's graphics protocol for superior quality.

🌈 ANSI Fallback (Universal)

Block character rendering with RGB colors using Chalk - works everywhere!

3. GIF Processing

  • FFmpeg-based frame extraction to temporary files
  • Controlled animation loop with configurable frame rates
  • Automatic cleanup of temporary resources

🎨 Terminal Compatibility

| Terminal | Strategy | Quality | |----------|----------|---------| | iTerm2 | Native | ⭐⭐⭐⭐⭐ | | Kitty | Kitty Protocol | ⭐⭐⭐⭐⭐ | | WezTerm | Kitty Protocol | ⭐⭐⭐⭐⭐ | | Warp | ANSI Fallback | ⭐⭐⭐⭐ | | Konsole | Kitty Protocol | ⭐⭐⭐⭐ | | Terminal.app | ANSI Fallback | ⭐⭐⭐ | | Windows Terminal | ANSI Fallback | ⭐⭐⭐ | | Standard xterm | ANSI Fallback | ⭐⭐⭐ |

🛠️ Development

Prerequisites

  • Node.js >= 20
  • npm, yarn, or pnpm

Setup

git clone https://github.com/pinkpixel-dev/pixelpop.git
cd pixelpop
npm install

Build

npm run build     # Compile TypeScript
npm run clean     # Clean dist directory
npm run prepare   # Full build (runs automatically on install)

Code Quality

npm run lint      # Run ESLint
npm run lint:fix  # Fix ESLint issues
npm run typecheck # TypeScript validation

Examples

Examples in examples/ are TypeScript. Run them with a TS runner like tsx or ts-node, or copy snippets into your own app:

npm run build

# Using tsx (recommended)
npx tsx examples/example.ts          # Static image demo
npx tsx examples/example_gif.ts      # Animated GIF demo

# Or using ts-node (if installed)
node --loader ts-node/esm examples/example.ts
node --loader ts-node/esm examples/example_gif.ts

📚 Documentation

Pixelpop includes comprehensive documentation with detailed guides, examples, and API references. Visit the /docs directory for complete documentation:

Quick API Overview

// Static images
await pixelPop.file(filePath, options?)     // Display image from file
await pixelPop.buffer(buffer, options?)     // Display image from buffer

// Animated GIFs  
const stop = await pixelPop.gifFile(filePath, options?)   // Play GIF from file
const stop = await pixelPop.gifBuffer(buffer, options?)   // Play GIF from buffer

// All methods support:
// - width/height: number | '50%' (percentage or pixels)
// - preserveAspectRatio: boolean (default: true)
// - maximumFrameRate: number (GIFs only, default: 30)
// - renderFrame: custom renderer function (GIFs only)

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Run the test suite: npm test
  5. Commit your changes: git commit -m 'Add amazing feature'
  6. Push to the branch: git push origin feature/amazing-feature
  7. Open a Pull Request

📄 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

✨ Created by Pink Pixel

Website: https://pinkpixel.dev Email: [email protected]