
Research
Namastex.ai npm Packages Hit with TeamPCP-Style CanisterWorm Malware
Malicious Namastex.ai npm packages appear to replicate TeamPCP-style Canister Worm tradecraft, including exfiltration and self-propagation.
Black Forest Labs API wrapper - FLUX and Kontext image generation for Node.js with CLI
A TypeScript/Node.js wrapper for the Black Forest Labs API that provides easy access to FLUX and Kontext image generation models. Generate stunning AI images with professional quality through a simple command-line interface.
This service follows the data-collection architecture pattern with organized data storage, automatic polling, retry logic, comprehensive logging, and CLI orchestration.
📺 Watch 3-minute CLI demo - Batch processing, auto-retry, and organized output in action.
# Install globally
npm install -g bfl-api
export BFL_API_KEY="my-bfl-api-key"
# Generate an image
bfl --flux-dev --prompt "a serene mountain landscape"
import { BflAPI } from 'bfl-api';
const api = new BflAPI();
// Generate and wait for image
const task = await api.generateFluxDev({
prompt: 'a serene mountain landscape',
width: 1024,
height: 768
});
const result = await api.waitForResult(task.id);
console.log('Image URL:', result.result.sample);
Full TypeScript support with exported types for all parameters and responses.
The Black Forest Labs API provides access to state-of-the-art image generation models. This Node.js service implements:
Full control text-to-image generation with adjustable steps and guidance.
Best for: Experimentation, fine-tuning parameters, development
Parameters:
width, height - Image dimensions (256-1440, divisible by 32)steps - Inference steps (1-50)guidance - Prompt adherence strength (1.5-5)Professional quality generation with Redux image prompting.
Best for: Production use, high-quality images, image-to-image with Redux
Parameters:
width, height - Image dimensions (256-1440, divisible by 32)image_prompt - Optional Redux image guidance (base64 or URL)Maximum quality with aspect ratio control and raw mode.
Best for: Cinematic outputs, specific aspect ratios, natural/raw aesthetics
Parameters:
aspect_ratio - Image proportions (21:9, 16:9, 4:3, 1:1, 3:4, 9:16, 9:21)raw - Enable raw/natural aesthetic mode (boolean)image_prompt - Optional image remixing (base64 or URL)Professional inpainting with mask-based editing for precise modifications.
Best for: Inpainting, object removal/replacement, selective editing with masks
Parameters:
image - Input image to edit (required, base64 or URL)mask - Mask defining edit region (required for JPG/JPEG, base64 or URL)steps - Inference steps (15-50)guidance - Prompt adherence strength (1.5-100)safety_tolerance - Content moderation strictness (0-6)Note: Requires either a separate mask image OR a PNG with an alpha channel (transparency) defining the edit region.
Inpainting with custom fine-tuned models for specialized styles and subjects.
Best for: Applying custom trained models to inpainting tasks, consistent style application, specialized subject matter
Parameters:
finetune_id - ID of your fine-tuned model (required)image - Input image to edit (required, base64 or URL)prompt - Description of desired changes (optional, default: '')mask - Mask defining edit region (required for JPG/JPEG, base64 or URL)finetune_strength - Model influence strength (0-2, API default: 1.1)steps - Inference steps (15-50)guidance - Prompt adherence strength (1.5-100)safety_tolerance - Content moderation strictness (0-6)Note: Requires a fine-tuned model ID from your BFL account. Same masking rules as regular Fill apply.
Professional image expansion/outpainting that extends images beyond original boundaries.
Best for: Image expansion, outpainting, adding context around images, extending canvases
Parameters:
image - Input image to expand (required, base64 or URL)top - Pixels to expand at top (0-2048, default: 0)bottom - Pixels to expand at bottom (0-2048, default: 0)left - Pixels to expand on left (0-2048, default: 0)right - Pixels to expand on right (0-2048, default: 0)prompt - Description of desired expansion (optional)steps - Inference steps (15-50, default: 50)guidance - Prompt adherence strength (1.5-100, default: 60)safety_tolerance - Content moderation strictness (0-6)output_format - Output format: 'jpeg' or 'png'prompt_upsampling - AI-powered prompt enhancement (boolean)Note: Specify at least one expansion direction (top, bottom, left, or right) with a value greater than 0.
Multi-reference image editing with context preservation.
Best for: Image editing, multi-reference composition, context-aware modifications
Parameters:
input_image - Base image to edit (required, base64 or URL)reference_image_1, reference_image_2, reference_image_3 - Optional context images (base64 or URL)Maximum quality multi-reference image editing.
Best for: High-end image editing, professional retouching
Parameters:
input_image - Base image to edit (required, base64 or URL)reference_image_1, reference_image_2, reference_image_3 - Optional context images (base64 or URL)Next-generation model with multi-image input support for contextual generation and editing.
Best for: Advanced multi-image editing, contextual generation, combining multiple references
Parameters:
width, height - Image dimensions (64-2048, divisible by 16)input_image through input_image_8 - Up to 8 input images for multi-reference (base64 or URL)prompt_upsampling - AI prompt enhancement (default: true)safety_tolerance - Content moderation level (0-5, default: 2)output_format - Output format: 'jpeg' or 'png'Flexible next-generation model with experimental multi-reference support.
Best for: Experimental multi-image workflows, flexible generation styles
Parameters:
width, height - Image dimensions (64-2048, divisible by 16)input_image through input_image_8 - Up to 8 input images for experimental multiref (base64 or URL)prompt_upsampling - AI prompt enhancement (default: true)safety_tolerance - Content moderation level (0-5, default: 2)output_format - Output format: 'jpeg' or 'png'You can provide your API key in multiple ways (listed in priority order):
Pass the API key directly when running commands:
bfl --api-key YOUR_API_KEY --flux-dev --prompt "a cat"
This is useful for one-off commands or testing.
Set the BFL_API_KEY environment variable in your shell:
# Add to your ~/.bashrc, ~/.zshrc, or equivalent
export BFL_API_KEY=your_actual_api_key_here
# Or use it for a single command
BFL_API_KEY=your_key bfl --flux-dev --prompt "a cat"
This is ideal for CI/CD pipelines and server environments.
Create a .env file in your project directory:
# In your project directory
echo "BFL_API_KEY=your_actual_api_key_here" > .env
This is best for project-specific configurations and when working on multiple projects.
Create a global config file at ~/.bfl/.env:
# Create config directory
mkdir -p ~/.bfl
# Add your API key
echo "BFL_API_KEY=your_actual_api_key_here" > ~/.bfl/.env
This is perfect for global npm installations (npm install -g bfl-api) where you want the API key available everywhere.
Security Note: Never commit .env files or expose your API key publicly. The .env file is automatically ignored by git.
# Install globally for CLI usage
npm install -g bfl-api
# Or install locally in your project
npm install bfl-api
# Clone the repository
git clone https://github.com/aself101/bfl-api.git
cd bfl-api
# Install dependencies
npm install
Dependencies:
axios - HTTP client for API callscommander - CLI argument parsingdotenv - Environment variable managementwinston - Logging frameworkThis package is written in TypeScript and includes full type definitions. All API methods, parameters, and responses are fully typed.
import {
BflAPI,
// Parameter types
FluxDevParams,
FluxProParams,
FluxProUltraParams,
FluxProFillParams,
FluxProExpandParams,
KontextProParams,
KontextMaxParams,
Flux2Params,
// Response types
TaskResult,
CreditsResult,
// Config types
BflApiOptions
} from 'bfl-api';
// Types are automatically inferred
const api = new BflAPI();
const task = await api.generateFluxDev({
prompt: 'a cat', // TypeScript will validate all parameters
width: 1024,
height: 768
});
All generation methods have strict parameter typing:
// TypeScript will catch invalid parameters at compile time
const task = await api.generateFluxDev({
prompt: 'a landscape',
width: 1024,
height: 768,
steps: 28, // number (1-50)
guidance: 3, // number (1.5-5)
seed: 42, // optional number
output_format: 'png' // 'jpeg' | 'png'
});
# Install dependencies
npm install
# Build TypeScript to JavaScript
npm run build
# Output is in dist/
ls dist/
# api.js, api.d.ts, cli.js, cli.d.ts, config.js, config.d.ts, utils.js, utils.d.ts
The CLI command depends on how you installed the package:
If installed globally (npm install -g bfl-api):
bfl --examples # Show 15+ usage examples
bfl --flux-dev --prompt "a cat" # Generate with FLUX.1 [dev]
bfl --credits # Check account credits
If installed locally in a project:
npx bfl --examples # Show 15+ usage examples
npx bfl --flux-dev --prompt "a cat" # Generate with FLUX.1 [dev]
npx bfl --credits # Check account credits
If working from source (cloned repository):
npm run bfl:examples # Show 15+ usage examples
npm run bfl -- --flux-dev --prompt "a cat" # Generate
npm run bfl:credits # Check credits
# Show examples (15+ usage examples)
bfl --examples
# Generate with FLUX.1 [dev]
bfl --flux-dev --prompt "a serene mountain landscape"
# Generate with FLUX 1.1 [pro] Ultra
bfl --flux-ultra --prompt "cinematic sunset" --aspect-ratio "21:9" --raw
# Edit image with Kontext Pro
bfl --kontext-pro --prompt "make it winter" --input-image ./photo.jpg
# Batch generation
bfl --flux-dev \
--prompt "a cat" \
--prompt "a dog" \
--prompt "a bird"
# Check credits
bfl --credits
Note: Examples below use bfl directly (global install). If using local install, prefix with npx: npx bfl --flux-dev ...
// If installed via npm
import { BflAPI } from 'bfl-api';
// If running from source
import { BflAPI } from './src/api.js';
// Initialize the API
const api = new BflAPI();
// Generate with FLUX.1 [dev]
const task = await api.generateFluxDev({
prompt: 'a beautiful sunset',
width: 1024,
height: 768,
steps: 28,
guidance: 3
});
// Wait for result
const result = await api.waitForResult(task.id);
console.log('Image URL:', result.result.sample);
# Global install
bfl [model] [options]
# Local install (use npx)
npx bfl [model] [options]
# From source (development)
npm run bfl -- [model] [options]
Choose one model:
--flux-dev # FLUX.1 [dev] - Full control
--flux-pro # FLUX 1.1 [pro] - Professional quality
--flux-ultra # FLUX 1.1 [pro] Ultra - Maximum quality
--flux-fill # FLUX.1 Fill [pro] - Inpainting/mask editing
--flux-fill-finetuned # FLUX.1 Fill [pro] Finetune - Custom model inpainting
--flux-expand # FLUX.1 Expand [pro] - Image expansion/outpainting
--flux-2-pro # FLUX.2 [PRO] - Multi-image generation/editing
--flux-2-flex # FLUX.2 [FLEX] - Experimental multi-reference
--kontext-pro # Kontext Pro - Image editing
--kontext-max # Kontext Max - Premium editing
--prompt <text> # Prompt (can specify multiple for batch)
--seed <number> # Random seed for reproducibility
--safety-tolerance <0-6> # Content moderation level (default: 2)
--output-format <jpeg|png> # Output format (default: jpeg)
--timeout <seconds> # Max wait time (default: 300)
--output-dir <path> # Custom output directory
--log-level <level> # DEBUG, INFO, WARNING, ERROR
--dry-run # Preview without generating
Note: All parameters are validated before making API calls. Invalid values (e.g., width not divisible by 32, steps > 50) will produce clear error messages, saving API credits.
--width <number> # 256-1440, multiple of 32 (default: 1024)
--height <number> # 256-1440, multiple of 32 (default: 768)
--steps <number> # 1-50 (default: 28)
--guidance <number> # 1.5-5 (default: 3)
--prompt-upsampling # Enable AI prompt enhancement
--width <number> # 256-1440, multiple of 32
--height <number> # 256-1440, multiple of 32
--image-prompt <path> # Input image for Redux (file or URL)
--prompt-upsampling # Enable AI prompt enhancement
--aspect-ratio <ratio> # e.g., 16:9, 21:9, 1:1 (default: 16:9)
--raw # Enable raw/natural mode
--image-prompt <path> # Input image for remixing (file or URL)
--image-prompt-strength <0-1> # Remix strength (default: 0.1)
--image <path> # Input image to edit (required, file or URL)
--mask <path> # Mask image defining edit region (required for JPG/JPEG)
--steps <number> # 15-50 (default: 28)
--guidance <number> # 1.5-100 (default: 3)
--prompt-upsampling # Enable AI prompt enhancement
Note: Either --mask is required, OR --image must be a PNG with an alpha channel (transparency). JPG/JPEG images require an explicit --mask parameter.
--finetune-id <id> # Fine-tuned model ID (required)
--image <path> # Input image to edit (required, file or URL)
--mask <path> # Mask image defining edit region (required for JPG/JPEG)
--finetune-strength <number> # Model influence 0-2 (default: 1.1)
--steps <number> # 15-50 (default: 50)
--guidance <number> # 1.5-100 (default: 60)
--prompt-upsampling # Enable AI prompt enhancement
Note: Requires a fine-tuned model ID from your BFL account. Same masking rules as regular Fill apply.
--image <path> # Input image to expand (required, file or URL)
--top <pixels> # Pixels to expand at top (0-2048, default: 0)
--bottom <pixels> # Pixels to expand at bottom (0-2048, default: 0)
--left <pixels> # Pixels to expand on left (0-2048, default: 0)
--right <pixels> # Pixels to expand on right (0-2048, default: 0)
--steps <number> # 15-50 (default: 50)
--guidance <number> # 1.5-100 (default: 60)
--prompt-upsampling # Enable AI prompt enhancement
Note: Specify at least one direction (top, bottom, left, or right) with a value greater than 0. Use --prompt to describe the content that should fill the expanded areas.
--input-image <path> # Primary input (required, file or URL)
--input-image-2 <path> # Additional reference (optional)
--input-image-3 <path> # Additional reference (optional)
--input-image-4 <path> # Additional reference (optional)
--width <number> # 64-2048, multiple of 16 (auto by default)
--height <number> # 64-2048, multiple of 16 (auto by default)
--input-image <path> # Primary input image (optional, file or URL)
--input-image-2 <path> # Additional reference (optional)
--input-image-3 <path> # Additional reference (optional)
--input-image-4 <path> # Additional reference (optional)
--input-image-5 <path> # Additional reference (experimental multiref)
--input-image-6 <path> # Additional reference (experimental multiref)
--input-image-7 <path> # Additional reference (experimental multiref)
--input-image-8 <path> # Additional reference (experimental multiref)
--prompt-upsampling # AI prompt enhancement (enabled by default for FLUX.2)
--safety-tolerance <0-5> # Content moderation level (default: 2)
Note: FLUX.2 models support up to 8 input images for advanced multi-reference generation. Dimensions must be divisible by 16 (not 32 like FLUX.1 models).
--examples # Show 15+ usage examples with tips
--credits # Check account credits balance
--get-result <task_id> # Poll specific task ID
generateFluxDev(params)Generate image using FLUX.1 [dev].
const task = await api.generateFluxDev({
prompt: 'a beautiful landscape',
width: 1024,
height: 768,
steps: 28,
guidance: 3,
seed: 42,
output_format: 'png'
});
generateFluxPro(params)Generate image using FLUX 1.1 [pro].
const task = await api.generateFluxPro({
prompt: 'professional portrait',
width: 1024,
height: 1024,
image_prompt: 'base64_or_url', // Optional Redux
seed: 42
});
generateFluxProUltra(params)Generate image using FLUX 1.1 [pro] Ultra.
const task = await api.generateFluxProUltra({
prompt: 'cinematic landscape',
aspect_ratio: '21:9',
raw: true,
image_prompt: 'base64_or_url', // Optional remix
image_prompt_strength: 0.3
});
generateFluxProFill(params)Inpainting with FLUX.1 Fill [pro] using masks.
const task = await api.generateFluxProFill({
prompt: 'replace with lush green grass',
image: 'base64_encoded_image', // Required
mask: 'base64_encoded_mask', // Required (or use PNG with alpha)
steps: 30,
guidance: 5,
safety_tolerance: 3,
output_format: 'png'
});
Note: The image parameter is required. Either provide a mask parameter, or use a PNG image with an alpha channel (transparency) defining the edit region.
generateFluxProFillFinetuned(params)Inpainting with fine-tuned FLUX.1 Fill [pro] model.
const task = await api.generateFluxProFillFinetuned({
finetune_id: 'my-custom-model', // Required
prompt: 'apply custom style', // Optional (default: '')
image: 'base64_encoded_image', // Required
mask: 'base64_encoded_mask', // Required (or use PNG with alpha)
finetune_strength: 1.2, // Optional (default: 1.1, range: 0-2)
steps: 35,
guidance: 60,
safety_tolerance: 2,
output_format: 'png'
});
Note: Requires finetune_id from your BFL account. Same masking rules as regular Fill apply.
generateFluxProExpand(params)Expand/outpaint images with FLUX.1 Expand [pro].
const task = await api.generateFluxProExpand({
prompt: 'extend with dramatic sky and clouds',
image: 'base64_encoded_image', // Required
top: 512, // Pixels to expand at top (0-2048)
bottom: 256, // Pixels to expand at bottom (0-2048)
left: 256, // Pixels to expand on left (0-2048)
right: 256, // Pixels to expand on right (0-2048)
steps: 30, // 15-50 (default: 50)
guidance: 60, // 1.5-100 (default: 60)
safety_tolerance: 2, // 0-6 (default: 2)
output_format: 'png', // 'jpeg' or 'png'
prompt_upsampling: true // Enable AI prompt enhancement
});
Note: The image parameter is required. Specify at least one expansion direction (top, bottom, left, or right) with a value greater than 0.
generateKontextPro(params)Edit image using Kontext Pro.
const task = await api.generateKontextPro({
prompt: 'make it look like winter',
input_image: 'base64_or_url', // Required
input_image_2: 'base64_or_url' // Optional
});
generateKontextMax(params)Edit image using Kontext Max.
const task = await api.generateKontextMax({
prompt: 'enhance colors and details',
input_image: 'base64_or_url', // Required
input_image_2: 'base64_or_url' // Optional
});
generateFlux2Pro(params)Generate or edit image using FLUX.2 [PRO] with multi-image support.
// Text-to-image generation
const task = await api.generateFlux2Pro({
prompt: 'A majestic castle on a cliff',
width: 1024,
height: 1024
});
// Image editing with context
const task = await api.generateFlux2Pro({
prompt: 'Add a dragon flying above',
input_image: 'base64_or_url',
input_image_2: 'base64_or_url' // Optional additional context
});
generateFlux2Flex(params)Generate or edit image using FLUX.2 [FLEX] with experimental multi-reference.
// Text-to-image generation
const task = await api.generateFlux2Flex({
prompt: 'A serene Japanese garden',
width: 1024,
height: 768
});
// Multi-reference generation (up to 8 images)
const task = await api.generateFlux2Flex({
prompt: 'Combine all elements',
input_image: 'base64_or_url',
input_image_2: 'base64_or_url',
input_image_3: 'base64_or_url'
});
getResult(taskId)Poll task once for current status.
const result = await api.getResult('abc123');
if (result.status === 'Ready') {
console.log('Image:', result.result.sample);
}
waitForResult(taskId, options)Auto-poll until complete with spinner and retry logic.
const result = await api.waitForResult('abc123', {
timeout: 300, // 5 minutes
pollInterval: 2, // 2 seconds
maxRetries: 3, // retry on transient errors
showSpinner: true // animated spinner
});
getUserCredits()Check account credits balance.
const credits = await api.getUserCredits();
console.log('Credits:', credits.credits);
getMyFinetunes()Get list of all fine-tuned models created by the user.
const { finetunes } = await api.getMyFinetunes();
console.log('Your finetunes:', finetunes);
// Example output: ['model-id-1', 'model-id-2', 'custom-style-abc']
// Use a finetune in generation
if (finetunes.length > 0) {
const task = await api.generateFluxProFillFinetuned({
finetune_id: finetunes[0],
image: 'base64_encoded_image',
prompt: 'apply custom style'
});
}
Note: Examples use bfl command (global install). For local install, use npx bfl instead.
bfl --flux-dev \
--prompt "a serene mountain landscape at sunset" \
--width 1024 \
--height 768 \
--steps 28 \
--guidance 3
bfl --flux-ultra \
--prompt "cinematic wide shot of a futuristic city" \
--aspect-ratio "21:9" \
--raw
bfl --kontext-pro \
--prompt "transform into a watercolor painting" \
--input-image ./photos/landscape.jpg
bfl --flux-dev \
--prompt "a red apple" \
--prompt "a green pear" \
--prompt "a yellow banana" \
--seed 42
bfl --flux-pro \
--prompt "same style but at night" \
--image-prompt ./reference.jpg \
--width 1024 \
--height 1024
# Using explicit mask (works with any image format)
bfl --flux-fill \
--prompt "fill with lush green grass and flowers" \
--image ./photos/landscape.jpg \
--mask ./photos/landscape_mask.png \
--steps 30 \
--guidance 5
# Using PNG with alpha channel (no mask needed)
bfl --flux-fill \
--prompt "remove object and fill background" \
--image ./photos/image_with_transparency.png \
--steps 28
Note: JPG/JPEG images require --mask parameter. PNG images can use alpha channel (transparency) as the mask.
# Expand image on all sides
bfl --flux-expand \
--prompt "extend with dramatic clouds and mountain vista" \
--image ./photos/landscape.jpg \
--top 512 --bottom 256 --left 256 --right 256 \
--steps 30 \
--guidance 60
# Vertical expansion only (portrait extension)
bfl --flux-expand \
--prompt "add sky with clouds above and ground below" \
--image ./photos/portrait.jpg \
--top 1024 --bottom 512 \
--steps 40
# Horizontal expansion with PNG output
bfl --flux-expand \
--prompt "expand cityscape to the sides" \
--image ./photos/city.jpg \
--left 640 --right 640 \
--output-format png \
--prompt-upsampling
Note: Specify at least one direction (top, bottom, left, right) to expand. Use --prompt to guide what content should fill the expanded areas.
// If installed via npm
import { BflAPI } from 'bfl-api';
import { imageToBase64 } from 'bfl-api/utils';
// If running from source
import { BflAPI } from './src/api.js';
import { imageToBase64 } from './src/utils.js';
const api = new BflAPI();
// Convert local image to base64
const inputImage = await imageToBase64('./photo.jpg');
// Edit with Kontext Pro
const task = await api.generateKontextPro({
prompt: 'make it look like a vintage photograph',
input_image: inputImage
});
// Wait for result with auto-polling
const result = await api.waitForResult(task.id, {
timeout: 300,
showSpinner: true
});
console.log('Generated image:', result.result.sample);
bfl --flux-2-pro \
--prompt "a majestic castle on a cliff at sunset" \
--width 1024 --height 1024
bfl --flux-2-pro \
--prompt "add a dragon flying in the sky" \
--input-image ./castle.jpg \
--width 1024 --height 1024
bfl --flux-2-flex \
--prompt "combine the subject and style" \
--input-image ./subject.jpg \
--input-image-2 ./style_reference.jpg
bfl --flux-2-flex \
--prompt "create a scene combining all elements" \
--input-image ./img1.jpg \
--input-image-2 ./img2.jpg \
--input-image-3 ./img3.jpg \
--input-image-4 ./img4.jpg \
--input-image-5 ./img5.jpg
Generated images and metadata are organized by model:
datasets/
└── bfl/
├── flux-dev/
│ ├── 2025-01-13_14-30-22_mountain_landscape.jpg
│ ├── 2025-01-13_14-30-22_mountain_landscape_metadata.json
│ └── ...
├── flux-pro/
│ └── ...
├── flux-ultra/
│ └── ...
├── flux-pro-fill/
│ └── ...
├── flux-2-pro/
│ └── ...
├── flux-2-flex/
│ └── ...
├── kontext-pro/
│ └── ...
└── kontext-max/
└── ...
Metadata Format:
{
"task_id": "abc123",
"model": "flux-dev",
"timestamp": "2025-01-13T14:30:22Z",
"parameters": {
"prompt": "a serene mountain landscape",
"width": 1024,
"height": 768,
"steps": 28,
"guidance": 3,
"seed": 42
},
"result": {
"status": "Ready",
"image_url": "https://...",
"image_path": "datasets/bfl/flux-dev/..."
}
}
This service implements production-ready security measures to protect your API keys and prevent common vulnerabilities:
xxx...abc1234).env files (never committed to version control).env, and global configNODE_ENV=production to enable generic error messages# Enable production mode for sanitized errors
export NODE_ENV=production
bfl --flux-dev --prompt "a cat"
When processing image URLs (for --image-prompt or --input-image), the service validates and blocks:
127.0.0.1, ::1, localhost10.x.x.x, 192.168.x.x, 172.16-31.x.x169.254.x.x (AWS/Azure metadata endpoints)metadata.google.internal, 169.254.169.254[::ffff:127.0.0.1], [::ffff:10.0.0.1], etc.This prevents attackers from using the service to access internal network resources, including sophisticated bypass attempts using IPv4-mapped IPv6 addresses and DNS rebinding attacks.
validateModelParams() before API callsThe service includes comprehensive error handling with retry logic:
Transient errors (network, 502, 503) are automatically retried with exponential backoff:
The CLI shows an animated spinner during generation:
⠋ Generating... Pending (12s elapsed, ~288s remaining)
On completion:
✓ Generation complete! (45.2s)
Error: BFL_API_KEY not found in environment variables
Solution: Create .env file with your API key:
BFL_API_KEY=your_api_key_here
Error: Content was moderated. Please revise your prompt.
Solution: Your prompt was flagged by safety filters. Try:
--safety-tolerance (0-6, lower is stricter)Error: Authentication failed. Please check your API key.
Solution:
.envError: Timeout after 300 seconds
Solution:
--timeout 600Error: Cannot find module 'axios'
Solution: Install dependencies:
cd bfl-api
npm install
Note: These npm scripts are only available when working from the source repository (cloned from GitHub). They are not available after installing via npm.
If you're using the installed package, use bfl (global) or npx bfl (local) instead.
npm run bfl # Run CLI
npm run bfl:help # Show help
npm run bfl:examples # Show 15+ usage examples
npm run bfl:credits # Check credits
npm run bfl:dev # Use FLUX.1 [dev]
npm run bfl:pro # Use FLUX 1.1 [pro]
npm run bfl:ultra # Use FLUX Ultra
npm run bfl:kontext-pro # Use Kontext Pro
npm run bfl:kontext-max # Use Kontext Max
Pass additional flags with --:
npm run bfl:dev -- --prompt "a cat" --width 512 --height 512
npm test # Run all 271 tests with Vitest
npm run test:watch # Watch mode for development
npm run test:ui # Interactive UI in browser
npm run test:coverage # Generate coverage report (89.58% overall)
Test Coverage:
Tests validate actual behavior including:
BFL API rate limits vary by account tier. The service automatically:
This package is part of the img-gen ecosystem. Check out these other AI generation services:
ideogram-api - Ideogram API wrapper for image generation, editing, remixing, and manipulationstability-ai-api - Stability AI API wrapper for Stable Diffusion 3.5 and image upscalinggoogle-genai-api - Google Generative AI (Imagen) wrapperopenai-api - OpenAI API wrapper for DALL-E and GPT Image generationDisclaimer: This project is an independent community wrapper and is not affiliated with Black Forest Labs.
This project is licensed under the MIT License (with Extra Silliness) - see the LICENSE file for details.
By using this software, you agree to generate at least one image of a cat wearing sunglasses (optional but encouraged).
Note: This service implements image generation endpoints. Fine-tuning endpoints can be added as needed following the same patterns established in the API class.
FAQs
Black Forest Labs API wrapper - FLUX and Kontext image generation for Node.js with CLI
We found that bfl-api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Malicious Namastex.ai npm packages appear to replicate TeamPCP-style Canister Worm tradecraft, including exfiltration and self-propagation.

Product
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.