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

@neplex/bgone

v1.0.0

Published

Node.js library to remove solid background colors from the images without AI/ML.

Readme

bgone

Node.js library to remove solid background colors from images without AI/ML based on bgone by Benface.

Features

  • Automatic background detection - Detects solid background colors by sampling image edges
  • Color unmixing - Separates foreground from background using advanced alpha blending algorithms
  • Foreground color deduction - Automatically deduce unknown foreground colors using "auto"
  • Strict and non-strict modes - Choose between exact color matching or flexible unmixing
  • Parallel processing - Utilizes all CPU cores for maximum performance
  • Cross-platform - Works on Windows, macOS, Linux, and more

Example Result

| Input | Output | | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | | Input | Output |

Example image from Unsplash

Installation

npm install @neplex/bgone
# or
yarn add @neplex/bgone
# or
pnpm add @neplex/bgone
# or
bun add @neplex/bgone
# or
deno add npm:@neplex/bgone

Quick Start

import { readFileSync, writeFileSync } from 'fs';
import { processImage, processImageSync, detectBackgroundColor } from '@neplex/bgone';

const input = readFileSync('input.png');

// Async processing (recommended for large images)
const output = await processImage({
  input,
  strictMode: false,
  trim: false,
});
writeFileSync('output.png', output);

// Sync processing
const outputSync = processImageSync({
  input,
  strictMode: false,
  trim: false,
});

CLI Usage

You can use bgone directly from the command line:

# Using npx (no installation required)
npx @neplex/bgone input.png

CLI Options

Usage: npx @neplex/bgone [options] <input> [output]

Remove solid background colors from images

Arguments:
  input                  Input image file
  output                 Output image file (defaults to input-bgone.png)

Options:
  -V, --version          output the version number
  -b, --bg <color>       Background color to remove (hex, e.g. #ffffff or fff)
  -f, --fg <colors...>   Foreground colors (hex or "auto" for deduction)
  -s, --strict           Strict mode - only use specified foreground colors
  -t, --threshold <value> Color closeness threshold (0.0-1.0)
  --trim                 Trim output to content bounding box
  --detect               Only detect and print background color, do not process
  -h, --help             display help for command

CLI Examples

# Fully automatic - detects background and removes it
npx @neplex/bgone input.png

# Specify output path
npx @neplex/bgone input.png output.png

# With explicit background color
npx @neplex/bgone input.png --bg=#ffffff
npx @neplex/bgone input.png -b fff

# With foreground color for optimized opacity
npx @neplex/bgone input.png --fg=#ff0000

# Multiple foreground colors
npx @neplex/bgone input.png --fg ff0000 00ff00 0000ff

# Foreground color deduction
npx @neplex/bgone input.png --fg auto
npx @neplex/bgone input.png --fg auto auto --bg ffffff

# Mix known and unknown colors
npx @neplex/bgone input.png --fg ff0000 auto

# Strict mode with foreground colors
npx @neplex/bgone input.png --strict --fg=#ff0000
npx @neplex/bgone input.png -s --fg auto

# With threshold and trim
npx @neplex/bgone input.png -f f00 0f0 00f -b fff -t 0.1 --trim

# Only detect background color
npx @neplex/bgone input.png --detect

API Reference

Types

interface RgbColor {
  r: number; // 0-255
  g: number; // 0-255
  b: number; // 0-255
}

interface RgbaColor {
  r: number; // 0-255
  g: number; // 0-255
  b: number; // 0-255
  a: number; // 0-255
}

interface NormalizedRgbColor {
  r: number; // 0.0-1.0
  g: number; // 0.0-1.0
  b: number; // 0.0-1.0
}

interface ProcessImageOptions {
  /** The input image buffer (PNG, JPEG, etc.) */
  input: Buffer;
  /** Foreground colors as hex strings. Use "auto" to deduce unknown colors. */
  foregroundColors?: string[];
  /** Background color as hex string. Auto-detected if not specified. */
  backgroundColor?: string;
  /** Restricts unmixing to only the specified foreground colors. */
  strictMode: boolean;
  /** Threshold for color closeness (0.0-1.0, default: 0.05) */
  threshold?: number;
  /** Trim output to bounding box of non-transparent pixels. */
  trim: boolean;
}

interface UnmixResult {
  /** Weight for each foreground color */
  weights: number[];
  /** Overall alpha value (0.0-1.0) */
  alpha: number;
}

Image Processing

processImage(options: ProcessImageOptions): Promise<Buffer>

Process an image asynchronously to remove its background. Returns a Promise that resolves to the processed image buffer (PNG format).

// Fully automatic - detects background and removes it
const output = await processImage({
  input: imageBuffer,
  strictMode: false,
  trim: false,
});

// With explicit background color
const output = await processImage({
  input: imageBuffer,
  backgroundColor: '#ffffff',
  strictMode: false,
  trim: true,
});

// With foreground colors for optimized opacity
const output = await processImage({
  input: imageBuffer,
  foregroundColors: ['#ff0000', '#00ff00'],
  backgroundColor: '#ffffff',
  strictMode: false,
  trim: false,
});

// Foreground color deduction using "auto"
const output = await processImage({
  input: imageBuffer,
  foregroundColors: ['auto'],
  backgroundColor: '#ffffff',
  strictMode: false,
  trim: false,
});

// Mix known and unknown colors
const output = await processImage({
  input: imageBuffer,
  foregroundColors: ['#ff0000', 'auto'],
  strictMode: true,
  trim: false,
});

// Strict mode - restricts to exact foreground colors
const output = await processImage({
  input: imageBuffer,
  foregroundColors: ['#ff0000'],
  backgroundColor: '#ffffff',
  strictMode: true,
  trim: false,
});

processImageSync(options: ProcessImageOptions): Buffer

Synchronous version of processImage. Use for smaller images or when async is not needed.

const output = processImageSync({
  input: imageBuffer,
  strictMode: false,
  trim: false,
});

Background Detection

detectBackgroundColor(input: Buffer): RgbColor

Detect the background color of an image by sampling its edges and corners.

const bgColor = detectBackgroundColor(imageBuffer);
console.log(`Background: rgb(${bgColor.r}, ${bgColor.g}, ${bgColor.b})`);

Image Utilities

trimImage(input: Buffer): Buffer

Trim an image to the bounding box of non-transparent pixels.

const trimmed = trimImage(imageBuffer);

Color Utilities

parseColor(hex: string): RgbColor

Parse a hex color string into an RGB color. Supports formats: "#ff0000", "ff0000", "#f00", "f00".

const red = parseColor('#ff0000');
// { r: 255, g: 0, b: 0 }

const green = parseColor('0f0');
// { r: 0, g: 255, b: 0 }

colorToNormalized(color: RgbColor): NormalizedRgbColor

Convert an RGB color (0-255) to a normalized RGB color (0.0-1.0).

const normalized = colorToNormalized({ r: 255, g: 128, b: 0 });
// { r: 1.0, g: 0.502, b: 0.0 }

normalizedToColor(color: NormalizedRgbColor): RgbColor

Convert a normalized RGB color (0.0-1.0) to an RGB color (0-255).

const rgb = normalizedToColor({ r: 1.0, g: 0.5, b: 0.0 });
// { r: 255, g: 128, b: 0 }

Color Unmixing

unmixColor(observed: RgbColor, foregroundColors: RgbColor[], background: RgbColor): UnmixResult

Unmix an observed color into foreground color components. Given an observed color and known foreground/background colors, determines how much of each foreground color contributed to the observed color.

const result = unmixColor(
  { r: 128, g: 0, b: 0 }, // observed color
  [{ r: 255, g: 0, b: 0 }], // foreground colors
  { r: 0, g: 0, b: 0 }, // background
);
console.log(result.weights); // [0.502...]
console.log(result.alpha); // 0.502...

computeUnmixResultColor(weights: number[], alpha: number, foregroundColors: RgbColor[]): RgbaColor

Compute the final RGBA color from an unmix result.

const rgba = computeUnmixResultColor([0.5, 0.5], 1.0, [
  { r: 255, g: 0, b: 0 },
  { r: 0, g: 255, b: 0 },
]);
// { r: 128, g: 128, b: 0, a: 255 }

compositeOverBackground(pixel: RgbaColor, background: RgbColor): RgbColor

Composite an RGBA pixel over an RGB background color. If the pixel is translucent (alpha < 255), pre-composes it over the background to produce an opaque equivalent.

const result = compositeOverBackground({ r: 255, g: 0, b: 0, a: 128 }, { r: 0, g: 0, b: 0 });
// { r: 128, g: 0, b: 0 }

Constants

getDefaultThreshold(): number

Get the default threshold for color closeness (0.05 = 5% of max RGB distance).

const threshold = getDefaultThreshold();
// 0.05

Processing Modes

Non-Strict Mode (default)

In non-strict mode, the algorithm finds the optimal foreground color and alpha that produces the observed color when alpha-blended with the background. This mode:

  • Works without specifying foreground colors
  • Allows any color to be used as foreground
  • Optimizes for minimum alpha (maximum transparency)
  • Always produces perfect reconstruction of the original image

Non-Strict Mode with Foreground Colors

When foreground colors are specified in non-strict mode:

  • Pixels close to specified foreground colors use the optimized unmixing algorithm
  • Pixels NOT close to any foreground color can use ANY color (preserves glows, gradients, etc.)
  • Uses the threshold option to determine "closeness"

Strict Mode

Strict mode restricts unmixing to only the specified foreground colors:

  • Requires at least one foreground color (can be "auto" for deduction)
  • Output pixels can only be a mix of the specified foreground colors
  • Best for images with known, limited color palettes

Foreground Color Deduction

Use "auto" in the foregroundColors array to automatically deduce unknown colors:

// Deduce one unknown color
const output = await processImage({
  input,
  foregroundColors: ['auto'],
  strictMode: true,
  trim: false,
});

// Mix known and unknown colors
const output = await processImage({
  input,
  foregroundColors: ['#ff0000', 'auto', 'auto'],
  strictMode: true,
  trim: false,
});

Performance

The library uses Rayon for parallel processing, utilizing all available CPU cores. For best performance:

  • Use processImage (async) for large images to avoid blocking the event loop
  • Use processImageSync for small images or batch processing
  • Consider using worker threads for processing multiple images

License

MIT

Credits

Based on bgone by Benface.