Installation
- npm
- pnpm
- yarn
- bun
Copy
npm install @poof-bg/js
Copy
pnpm add @poof-bg/js
Copy
yarn add @poof-bg/js
Copy
bun add @poof-bg/js
Quick Start
Copy
import { Poof } from '@poof-bg/js';
import fs from 'fs/promises';
const poof = new Poof({ apiKey: 'poof_your_api_key' });
const image = await fs.readFile('photo.jpg');
const result = await poof.remove(image);
await fs.writeFile('result.png', result);
Authentication
The SDK looks for your API key in this order:- Passed directly:
new Poof({ apiKey: '...' }) - Environment variable:
POOF_API_KEY
Copy
import { Poof } from '@poof-bg/js';
// Option 1: Pass directly
const poof = new Poof({ apiKey: 'poof_your_api_key' });
// Option 2: Use environment variable (recommended)
// POOF_API_KEY=poof_your_api_key
const poof = new Poof();
Usage Examples
From Buffer
Copy
import { Poof } from '@poof-bg/js';
import fs from 'fs/promises';
const poof = new Poof();
const image = await fs.readFile('photo.jpg');
const result = await poof.remove(image);
await fs.writeFile('result.png', result);
From File Path (Node.js)
Copy
import { Poof } from '@poof-bg/js';
import fs from 'fs/promises';
const poof = new Poof();
const result = await poof.removeFile('photo.jpg');
await fs.writeFile('result.png', result);
From URL
Copy
const response = await fetch('https://example.com/photo.jpg');
const image = Buffer.from(await response.arrayBuffer());
const result = await poof.remove(image);
With Options
Copy
// White background JPEG
const result = await poof.remove(image, {
format: 'jpg',
channels: 'rgb',
bgColor: '#ffffff',
});
// Small cropped thumbnail
const result = await poof.remove(image, {
size: 'small',
crop: true,
});
// WebP for web
const result = await poof.remove(image, {
format: 'webp',
size: 'medium',
});
Response Metadata
Access processing metadata from the response:Copy
const response = await poof.removeWithMetadata(image);
console.log(response.data); // Buffer - the processed image
console.log(response.requestId); // string - unique request ID
console.log(response.processingTimeMs); // number - processing time
console.log(response.width); // number - output width
console.log(response.height); // number - output height
Parallel Processing
Copy
import { Poof } from '@poof-bg/js';
import fs from 'fs/promises';
import path from 'path';
const poof = new Poof();
async function processImages(imagePaths: string[]) {
const results = await Promise.all(
imagePaths.map(async (imagePath) => {
const image = await fs.readFile(imagePath);
const result = await poof.remove(image);
const outputPath = imagePath.replace(/\.[^.]+$/, '_no_bg.png');
await fs.writeFile(outputPath, result);
return outputPath;
})
);
return results;
}
await processImages(['photo1.jpg', 'photo2.jpg', 'photo3.jpg']);
Account Info
Check your credit balance:Copy
const account = await poof.getAccount();
console.log(`Plan: ${account.plan}`);
console.log(`Credits used: ${account.usedCredits}/${account.maxCredits}`);
console.log(`Remaining: ${account.maxCredits - account.usedCredits}`);
Error Handling
Copy
import { Poof, PoofError, AuthenticationError, PaymentRequiredError, RateLimitError } from '@poof-bg/js';
const poof = new Poof();
try {
const result = await poof.remove(image);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Check your API key');
} else if (error instanceof PaymentRequiredError) {
console.error('Out of credits — upgrade your plan');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Request ID: ${error.requestId}`);
} else if (error instanceof PoofError) {
console.error(`API error: ${error.message} (${error.requestId})`);
} else {
throw error;
}
}
Retry with Backoff
Copy
async function removeWithRetry(
poof: Poof,
image: Buffer,
maxRetries = 3
): Promise<Buffer> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await poof.remove(image);
} catch (error) {
if (error instanceof RateLimitError && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
Configuration
Copy
const poof = new Poof({
apiKey: 'poof_your_api_key',
baseUrl: 'https://api.poof.bg/v1', // Default
timeout: 30000, // Request timeout in ms
});
TypeScript Types
Full type definitions are included:Copy
import type {
Poof,
RemoveOptions,
AccountInfo,
Format,
Size,
Channels,
} from '@poof-bg/js';
const options: RemoveOptions = {
format: 'png',
size: 'full',
crop: false,
};
Framework Examples
Express.js
Copy
import express from 'express';
import multer from 'multer';
import { Poof } from '@poof-bg/js';
const app = express();
const upload = multer();
const poof = new Poof();
app.post('/remove-background', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No image provided' });
}
try {
const result = await poof.remove(req.file.buffer);
res.set('Content-Type', 'image/png');
res.send(result);
} catch (error) {
res.status(500).json({ error: 'Processing failed' });
}
});
app.listen(3000);
Next.js API Route
Copy
// app/api/remove-bg/route.ts
import { Poof } from '@poof-bg/js';
import { NextRequest, NextResponse } from 'next/server';
const poof = new Poof();
export async function POST(request: NextRequest) {
const formData = await request.formData();
const file = formData.get('image') as File;
if (!file) {
return NextResponse.json({ error: 'No image' }, { status: 400 });
}
const buffer = Buffer.from(await file.arrayBuffer());
const result = await poof.remove(buffer);
return new NextResponse(result, {
headers: { 'Content-Type': 'image/png' },
});
}