Complete documentation for all Pixelpop methods, types, and interfaces.
- Import Statement
- Static Image Methods
- Animated GIF Methods
- Types & Interfaces
- Error Handling
- Examples
// ES Module (ESM-only package)
import pixelPop from "@pinkpixel/pixelpop";Note: @pinkpixel/pixelpop is ESM-only (package.json has "type": "module"). Use ESM in your project, or use dynamic import() from CommonJS if needed.
Display an image from a file path.
| Parameter | Type | Required | Description |
|---|---|---|---|
filePath |
string |
✅ | Path to the image file |
options |
RenderOptions |
❌ | Display configuration options |
- Type:
Promise<string> - Description: Rendered image as a string (for ANSI fallback) or empty string (for native rendering)
const output = await pixelPop.file("./my-image.jpg", {
width: "60%",
height: 20,
preserveAspectRatio: true,
});
console.log(output);Display an image from a buffer.
| Parameter | Type | Required | Description |
|---|---|---|---|
buffer |
Readonly<Uint8Array> |
✅ | Image data as a buffer |
options |
RenderOptions |
❌ | Display configuration options |
- Type:
Promise<string> - Description: Rendered image as a string (for ANSI fallback) or empty string (for native rendering)
import { readFile } from "fs/promises";
const imageBuffer = await readFile("./screenshot.png");
const output = await pixelPop.buffer(imageBuffer, {
width: 80,
preserveAspectRatio: true,
});
console.log(output);Play an animated GIF from a file path.
| Parameter | Type | Required | Description |
|---|---|---|---|
filePath |
string |
✅ | Path to the GIF file |
options |
GifOptions |
❌ | Animation configuration options |
- Type:
Promise<() => void> - Description: Function to stop the animation
const stop = await pixelPop.gifFile("./loading.gif", {
width: "50%",
maximumFrameRate: 30,
});
// Stop animation after 5 seconds
setTimeout(stop, 5000);Play an animated GIF from a buffer.
| Parameter | Type | Required | Description |
|---|---|---|---|
buffer |
Readonly<Uint8Array> |
✅ | GIF data as a buffer |
options |
GifOptions |
❌ | Animation configuration options |
- Type:
Promise<() => void> - Description: Function to stop the animation
import { readFileSync } from "fs";
const gifBuffer = readFileSync("./animation.gif");
const stop = await pixelPop.gifBuffer(gifBuffer, {
maximumFrameRate: 15,
preserveAspectRatio: true,
});
// Animation will continue until stoppedConfiguration options for static image rendering.
interface RenderOptions {
readonly width?: DimensionValue;
readonly height?: DimensionValue;
readonly preserveAspectRatio?: boolean;
}| Property | Type | Default | Description |
|---|---|---|---|
width |
DimensionValue |
'100%' |
Image width (pixels or percentage) |
height |
DimensionValue |
'100%' |
Image height (pixels or percentage) |
preserveAspectRatio |
boolean |
true |
Maintain original image proportions |
Configuration options for animated GIF rendering.
interface GifOptions extends RenderOptions {
readonly maximumFrameRate?: number;
readonly renderFrame?: RenderFrame;
}| Property | Type | Default | Description |
|---|---|---|---|
maximumFrameRate |
number |
30 |
Maximum frames per second (1-60) |
renderFrame |
RenderFrame |
Built-in smooth renderer | Custom frame rendering function |
...all RenderOptions |
Inherited from RenderOptions |
Type for specifying image dimensions.
type DimensionValue = number | `${number}%`;// Pixel values
const width: DimensionValue = 100;
const height: DimensionValue = 50;
// Percentage values
const responsiveWidth: DimensionValue = "80%";
const responsiveHeight: DimensionValue = "50%";Type for custom frame rendering functions.
type RenderFrame = ((text: string) => void) & {
done?: () => void;
};- Function:
(text: string) => void- Called for each frame with rendered frame content - done (optional):
() => void- Called when animation completes or stops
const customRenderer: RenderFrame = (frame: string) => {
// Clear screen and display frame
process.stdout.write("\x1Bc");
console.log("🎬 Custom Animation:");
console.log(frame);
};
customRenderer.done = () => {
console.log("\n✅ Animation finished!");
};Pixelpop automatically detects your terminal's capabilities and chooses the optimal rendering strategy:
| Terminal | Strategy | Quality | Features |
|---|---|---|---|
| iTerm2 | Native | ⭐⭐⭐⭐⭐ | Built-in image protocols |
| Kitty | Kitty Protocol | ⭐⭐⭐⭐⭐ | Direct image rendering |
| WezTerm | Kitty Protocol | ⭐⭐⭐⭐⭐ | High-quality graphics |
| Konsole | Kitty Protocol | ⭐⭐⭐⭐ | KDE terminal support |
| VS Code | ANSI Fallback | ⭐⭐⭐ | Integrated terminal |
| Windows Terminal | ANSI Fallback | ⭐⭐⭐ | Modern Windows support |
| Alacritty | ANSI Fallback | ⭐⭐⭐ | GPU-accelerated |
| Standard terminals | ANSI Fallback | ⭐⭐⭐ | Universal compatibility |
Pixelpop checks these environment variables:
// Terminal detection (automatic)
process.env.TERM_PROGRAM; // 'iTerm.app', 'WezTerm', 'konsole'
process.env.TERM; // 'xterm-kitty'
process.env.KITTY_WINDOW_ID; // Present in Kitty
process.env.KONSOLE_VERSION; // Konsole version
process.env.WT_SESSION; // Windows Terminal- Native Support - Uses terminal's built-in image protocols (iTerm2)
- Kitty Protocol - Direct image rendering for compatible terminals
- ANSI Fallback - Block character rendering with RGB colors (universal)
Pixelpop provides comprehensive error handling for various failure scenarios:
try {
await pixelPop.file("./nonexistent.jpg");
} catch (error) {
console.error("Image file not found:", error.message);
}try {
const invalidBuffer = new Uint8Array([1, 2, 3]);
await pixelPop.buffer(invalidBuffer);
} catch (error) {
console.error("Invalid image data:", error.message);
}try {
await pixelPop.file("./image.jpg", {
width: "invalid-dimension" as any,
});
} catch (error) {
console.error("Invalid dimension value:", error.message);
}try {
await pixelPop.gifFile("./corrupted.gif");
} catch (error) {
console.error("GIF processing failed:", error.message);
}- Always use try-catch for async operations
- Validate file paths before processing
- Check buffer validity when using buffer methods
- Handle animation stop gracefully
// Robust error handling example
async function displayImageSafely(imagePath: string) {
try {
const output = await pixelPop.file(imagePath, {
width: "80%",
preserveAspectRatio: true,
});
console.log(output);
} catch (error) {
if (error.code === "ENOENT") {
console.error("Image file not found:", imagePath);
} else if (error.message.includes("dimension")) {
console.error("Invalid dimension specified");
} else {
console.error("Failed to display image:", error.message);
}
}
}// Adapt to terminal size
await pixelPop.file("./hero.jpg", {
width: "100%",
preserveAspectRatio: true,
});// Specific pixel dimensions
await pixelPop.file("./icon.png", {
width: 64,
height: 64,
preserveAspectRatio: false,
});import { createReadStream } from "fs";
const stream = createReadStream("./image.jpg");
const chunks: Buffer[] = [];
stream.on("data", (chunk) => chunks.push(chunk));
stream.on("end", async () => {
const buffer = Buffer.concat(chunks);
await pixelPop.buffer(buffer, { width: "50%" });
});let animationCount = 0;
const maxLoops = 3;
async function playGifWithLoopLimit() {
const stop = await pixelPop.gifFile("./loop.gif", {
width: "60%",
maximumFrameRate: 24,
});
// Stop after specific number of loops
const checkLoop = setInterval(() => {
animationCount++;
if (animationCount >= maxLoops) {
stop();
clearInterval(checkLoop);
console.log("Animation completed!");
}
}, 2000); // Assuming 2 second loop duration
}import chalk from "chalk";
const progressRenderer: RenderFrame = (frame: string) => {
const timestamp = new Date().toLocaleTimeString();
process.stdout.write(`\x1Bc`); // Clear screen
console.log(chalk.blue(`🎬 Animation at ${timestamp}`));
console.log(frame);
};
progressRenderer.done = () => {
console.log(chalk.green("✅ Animation finished!"));
};
await pixelPop.gifFile("./demo.gif", {
renderFrame: progressRenderer,
maximumFrameRate: 20,
});import express from "express";
import pixelPop from "@pinkpixel/pixelpop";
const app = express();
app.get("/image/:filename", async (req, res) => {
try {
const output = await pixelPop.file(`./images/${req.params.filename}`, {
width: 80,
preserveAspectRatio: true,
});
res.type("text/plain").send(output);
} catch (error) {
res.status(404).send("Image not found");
}
});
app.listen(3000);#!/usr/bin/env node
import { program } from "commander";
import pixelPop from "@pinkpixel/pixelpop";
program
.command("show <image>")
.option("-w, --width <width>", "Image width", "80%")
.option("-h, --height <height>", "Image height")
.action(async (imagePath, options) => {
try {
await pixelPop.file(imagePath, {
width: options.width,
height: options.height,
preserveAspectRatio: true,
});
} catch (error) {
console.error("Error:", error.message);
process.exit(1);
}
});
program.parse();Made with ❤️ by Pink Pixel
"Dream it, Pixel it" ✨