
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
AI-powered image generator supporting Google Gemini and Fal Nano Banana 2. Supports image generation from text prompts and image modification with reference images (Gemini).
npm install genmix
You can also add GenMix as a skill for AI agentic development:
npx skills add https://github.com/clasen/GenMix --skill genmix
Create a .env file in your project root:
GEMINI_API_KEY=your_api_key_here
FAL_API_KEY=your_fal_api_key_here
GEMINI_API_KEY is used with provider gemini and FAL_API_KEY is used with provider fal.
GenMix shines when combining multiple images with specific instructions using its intuitive chainable API:
import { GeminiGenerator } from 'genmix';
const generator = new GeminiGenerator();
const result = await generator
.pro() // Use the Pro model for best results
.addReference('./person.jpg', 'Use this person as the main subject')
.addReference('./background.jpg', 'Use this as the background setting')
.generate('A photo of the person standing in the background setting, cinematic lighting');
await generator.save({ filename: 'composite-result' });
import { GeminiGenerator, FalGenerator } from 'genmix';
const gemini = new GeminiGenerator({ apiKey: process.env.GEMINI_API_KEY });
const fal = new FalGenerator({ apiKey: process.env.FAL_API_KEY });
await gemini.flash().generate('A cinematic portrait with dramatic lighting');
await fal.generate('A cinematic portrait with dramatic lighting', {
numberOfImages: 1,
quality: '1K',
aspectRatio: '1:1'
});
Fal models available in this integration:
flash (or banana2) -> fal-ai/nano-banana-2/edit (image-to-image editing)pro (or banana-pro) -> fal-ai/nano-banana-pro/edit (image-to-image editing)You can easily switch between the Pro and Flash models using chainable methods:
import { GeminiGenerator } from 'genmix';
const generator = new GeminiGenerator();
// Use the Pro model
await generator
.pro()
.generate('A highly detailed portrait of a cat');
// Switch to the Flash model
await generator
.flash()
.generate('A quick sketch of a dog');
import { GeminiGenerator } from 'genmix';
const generator = new GeminiGenerator();
// Generate an image
const result = await generator.generate(
'A futuristic city with flying cars, cyberpunk style',
{
numberOfImages: 1,
quality: '2K',
aspectRatio: '16:9'
}
);
// Save images
const savedPaths = await generator.save({ directory: './output' });
console.log('Images saved:', savedPaths);
// Modify an existing image
const result = await generator.generate(
'Transform this image to have sunset lighting with warm orange tones',
{
referenceImage: './my-image.png', // Local path
quality: '2K',
numberOfImages: 1
}
);
const savedPaths = await generator.save({ directory: './output' });
const result = await generator.generate(
'Convert this photo into a watercolor painting',
{
referenceImage: 'https://example.com/image.jpg', // URL
quality: '1K'
}
);
generator.save({ directory: './output' });
new GeminiGenerator({
apiKey: string, // Your Google API key (required)
modelId: string // Model to use (optional, default: 'gemini-3-pro-image-preview')
})
new FalGenerator({
apiKey: string, // Your Fal API key (required)
modelId: string // Optional: FalGenerator.MODELS.BANANA_2 or BANANA_PRO_EDIT
})
generator.pro() // Switches to the gemini-3-pro-image-preview model
generator.flash() // Switches to the gemini-3.1-flash-image-preview model
Both methods are chainable and return the generator instance.
Fal generator model methods:
fal.banana2() // fal-ai/nano-banana-2/edit (image editing)
fal.bananaPro() // fal-ai/nano-banana-pro/edit (image editing)
fal.pro() // alias of bananaPro()
fal.flash() // alias of banana2()
You can also use chainable methods to add one or multiple reference images before calling generate():
generator.addReference(image, description) // Adds a reference image (path, URL, Buffer)
generator.clearReferences() // Removes all queued reference images
For fal (flash and pro), references can be URL, data URI, local file path, or Buffer.
await generator.generate(prompt, options)
Parameters:
| Option | Type | Description | Default |
|---|---|---|---|
prompt | string | Description of what you want to generate | - |
options.referenceImage | string/Buffer | Reference image (path, URL, Base64, Buffer) | - |
options.numberOfImages | number | Number of images to generate | 1 |
options.quality | string | Quality: '1K', '2K', '4K' | - |
options.aspectRatio | string | Aspect ratio: '1:1', '16:9', '4:3', etc. | - |
options.width | number | Final output width in pixels (requires height) | - |
options.height | number | Final output height in pixels (requires width) | - |
await generator.save(options)
Parameters:
| Option | Type | Description | Default |
|---|---|---|---|
options.directory | string | Target directory path to save images | '.' |
options.filename | string | Custom filename (without extension). If not provided, uses hash-based filename | - |
options.extension | string | File format: 'jpg', 'png', 'webp', 'avif', 'tiff' | 'jpg' |
Examples:
// Save to specific directory with auto-generated filename (jpg by default)
await generator.save({ directory: './output' });
// Save as PNG
await generator.save({ directory: './output', extension: 'png' });
// Save to specific directory with custom filename
await generator.save({ directory: './output', filename: 'my-image' });
// Save as WebP with custom filename
await generator.save({ directory: './output', filename: 'my-image', extension: 'webp' });
// Save to current directory with custom filename
await generator.save({ filename: 'my-image' });
// Save to current directory with auto-generated filename (jpg)
await generator.save();
You can request high generation quality and still force an exact final output size directly in generate():
const generator = new GeminiGenerator();
await generator.generate('App icon, flat minimal style', {
quality: '4K', // generation quality (independent)
width: 400,
height: 400
});
// width/height resize is automatically applied on save()
await generator.save({ filename: 'icon-400x400', extension: 'png' });
If you also pass aspectRatio, it must match the ratio derived from width/height.
Note:
filename_0.jpg, filename_1.jpg, etc.const result = await generator.generate(
'Transform this photo into a Van Gogh style painting with visible brush strokes',
{
referenceImage: './photo.jpg',
quality: '4K'
}
);
const result = await generator.generate(
'Change the lighting to dramatic studio lighting with strong shadows',
{
referenceImage: './portrait.png',
quality: '2K'
}
);
const result = await generator.generate(
'Add dramatic clouds and enhance colors',
{
referenceImage: './landscape.jpg',
numberOfImages: 3,
quality: '1K'
}
);
// Generates 3 variations of the same modification
import fs from 'fs';
const imageBuffer = fs.readFileSync('./image.png');
const result = await generator.generate(
'Make this image look cinematic',
{
referenceImage: imageBuffer
}
);
GenMix accepts reference images in multiple formats:
'./image.png''https://example.com/image.jpg''data:image/png;base64,iVBORw0KG...'Buffer.from(...)Supported image formats: PNG, JPEG, GIF, WEBP
try {
const result = await generator.generate(prompt, options);
if (result.images && result.images.length > 0) {
const paths = generator.save({ directory: './output' });
console.log('Success!', paths);
} else {
console.log('No images generated');
}
} catch (error) {
console.error('Error:', error.message);
// Common errors:
// - 'API Key is required'
// - 'Failed to read reference image file'
// - 'Failed to download reference image from URL'
// - 'Gemini API Error: ...'
}
genmix/
└── generators/
│ ├── BaseGenerator.js # Base class with utilities
│ ├── GeminiGenerator.js # Gemini API implementation
│ └── FalGenerator.js # Fal Nano Banana 2 implementation
├── demo/
│ ├── example.js # Basic examples
│ └── example-translation.js # Translate image
├── index.js # Entry point
└── README.md
Clear Prompts: Be specific about what you want
// ✅ Good
'Add dramatic sunset lighting with orange and pink tones in the sky'
// ❌ Vague
'Make it better'
Appropriate Quality:
1K: Quick tests2K: General use4K: High quality (slower)Image Size: Reference images between 512x512 and 2048x2048 work best
Result Caching: Images are automatically saved with unique hash based on the prompt
Install GenMix globally to use it from the command line:
npm install -g genmix
If no API key is available, the CLI asks for it on first use and saves it to:
~/.genmix/config.json
You can set or update it explicitly anytime:
genmix --config
API key resolution order in CLI:
GEMINI_API_KEY or FAL_API_KEY)~/.genmix/config.json) using geminiApiKey/apiKey or falApiKey# Show help
genmix --help
# Generate from prompt
genmix "A futuristic city with flying cars, cyberpunk style"
# Generate multiple images
genmix "A cozy cabin in winter" -n 2 -q 2K -r 16:9 -m flash
# Use Fal Nano Banana 2 edit (flash) with reference
genmix "Restyle this room with warm sunset mood" --provider fal -m flash --ref "./room.jpg" -n 2 -q 2K -r 16:9
# Use Fal Nano Banana Pro (edit) with reference
genmix "make this scene cinematic" --provider fal -m banana-pro --ref "https://example.com/input.png"
--output accepts either:
# Save to a directory (auto-generated hash filename)
genmix "Watercolor fox logo" --output ./output
# Save to exact file path and filename
genmix "Watercolor fox logo" --output ./output/logo-fox.png
You can ask the model for high generation quality (for example 4K) and still force a final exact output size.
When you pass target dimensions, GenMix CLI:
400x400 -> 1:1, 1920x1080 -> 16:9)1K, 2K, or 4K)# Ask for 4K quality, deliver exact 400x400 output
genmix "app icon, flat minimal style" -q 4K --width 400 --height 400 --output ./output/icon.png
If you also pass --ratio, it must match the derived ratio from the target size.
Use --ref <path:text> to add reference images with optional guidance text:
# Reference path only
genmix "Restyle this room" --ref ./room.jpg
# Reference path + description
genmix "Restyle this room" --ref "./room.jpg:keep composition and camera angle"
# Multiple references with descriptions
genmix "Create product ad scene" \
--ref "./product.png:use as main subject" \
--ref "./bg.jpg:use as background mood"
# References for fal models (URL, data URI, or local path)
genmix "Edit this image for a magazine look" \
--provider fal -m flash \
--ref "./photo.png"
-n, --number <N> Number of images (default: 1)
-q, --quality <1K|2K|4K> Image quality (default: 1K)
-p, --provider <gemini|fal> Provider (default: gemini)
-r, --ratio <ratio> Aspect ratio (default: 1:1 for gemini, auto for fal)
-m, --model <...> gemini: pro|flash (default: flash)
fal: pro|flash (aliases: banana-pro|banana2|2, default: flash)
-o, --output <path> Output directory or full output file path
-f, --format <format> Output format when output is a directory (default: jpg)
--width <px> Final output width in pixels (requires --height)
--height <px> Final output height in pixels (requires --width)
--ref <path[:text]> Reference image (path/URL/data URI); for URL descriptions use URL::description
--no-sharp Save raw model bytes without Sharp conversion (disables resizing)
--config Set/update persisted API key
--help Show help
MIT
Contributions are welcome! Please open an issue or pull request.
FAQs
AI-powered image generator supporting Google Gemini and Fal Nano Banana 2.
The npm package genmix receives a total of 45 weekly downloads. As such, genmix popularity was classified as not popular.
We found that genmix 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.