ZyVOP Logo
Content That Connects
SeriesAI NewsLeaderboardWrite for Us
ZyVOP Logo
Content That Connects

Empowering developers and creators with cutting-edge insights, comprehensive tutorials, and innovative solutions for the digital future.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

© 2026 ZyVOP. Crafted with care for the developer community.

Made with ❤️ by the ZyVOP team
All systems operational
HomeHow We Built Dynamic AI Blog Covers using NestJS and Hugging Face FLUX

How We Built Dynamic AI Blog Covers using NestJS and Hugging Face FLUX

A deep dive into integrating Hugging Face's FLUX model into a NestJS backend to automatically generate and optimize blog cover images.

Sanju Singh
Sanju SinghSenior Developer
August 4, 2026
3 min read
#NestJS#AI#TypeScript#webdev
👍2

When building Zyvop—a platform designed to help developers write once and distribute everywhere—we realized a major friction point for writers: finding a good cover image.

Developers want to write code and explain technical concepts, not spend 30 minutes browsing Unsplash for a generic stock photo of a laptop. We wanted to solve this by automatically generating beautiful, context-aware cover images for every post using AI.

Here is exactly how we built a dynamic image generation pipeline using NestJS, Hugging Face's FLUX model, and Sharp for image optimization.

The Architecture

We needed a system that was fast, reliable, and produced high-quality images. We settled on the following stack:

  • Backend: NestJS

  • Model: Black Forest Labs' FLUX.1-schnell (via Hugging Face Inference API)

  • Image Processing: sharp (for resizing and converting to WebP)

The schnell variant of FLUX is incredibly fast and perfect for on-the-fly generation without making the user wait 30 seconds for an image.

Step 1: The Prompt Engineering

The first step was taking a user's blog post title and turning it into a prompt that reliably produces clean, modern graphics.

In our ImageGenerationService, we built a simple prompt generator:

buildPromptFromTitle(title: string, keywords?: string[]): string {
  const keywordStr = keywords?.length ? `, related to ${keywords.slice(0, 3).join(', ')}` : '';
  return `Simple, clean modern blog cover image. Professional and elegant. Topic: "${title}"${keywordStr}. With best background but remember this image has text`;
}

The trick here is keeping the prompt constrained. By appending "Simple, clean modern blog cover image," we prevent the AI from generating overly chaotic or photorealistic images that distract from the article title.

Step 2: Hitting the Hugging Face API

Next, we make a POST request to the Hugging Face router. NestJS makes it easy to inject the ConfigService to securely manage our API keys.

async generateImage(prompt: string): Promise<Buffer | null> {
  const modelEndpoint = 'https://router.huggingface.co/hf-inference/models/black-forest-labs/FLUX.1-schnell';
  
  const response = await fetch(modelEndpoint, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${this.apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      inputs: prompt,
      parameters: {
        width: 1024,
        height: 576, // Standard 16:9 aspect ratio
        seed: Math.floor(Math.random() * 1000000), // Randomize for variety
      },
    }),
  });

  if (!response.ok) {
    throw new Error(`HF API error: ${response.status}`);
  }

  const arrayBuffer = await response.arrayBuffer();
  return Buffer.from(arrayBuffer);
}

We specifically request a 1024x576 image to maintain a standard 16:9 aspect ratio, which is ideal for Open Graph cards (Twitter/LinkedIn previews) and blog headers.

Step 3: Optimization with Sharp

Raw AI-generated images can be massive (often several megabytes). Serving a 3MB image as a blog cover is terrible for Web Vitals and user experience.

Before saving the image, we run it through sharp to resize it (upscaling slightly to 1600x900 for high-DPI displays) and convert it to a highly compressed WebP format.

import * as sharp from 'sharp';

async generateAndSave(prompt: string): Promise<{ key: string; publicUrl: string } | null> {
  const imageBuffer = await this.generateImage(prompt);
  if (!imageBuffer) return null;

  const now = Date.now();
  const rand = Math.random().toString(36).slice(2);
  const key = `posts/covers/ai-${now}-${rand}.webp`;

  // ⚡ Process with sharp for optimization
  const optimizedBuffer = await sharp(imageBuffer)
    .resize(1600, 900, { fit: 'cover' })
    .webp({ quality: 85 }) // Compress to WebP!
    .toBuffer();

  // Save to local filesystem (or S3)
  const uploadsRoot = join(process.cwd(), 'uploads');
  const absPath = join(uploadsRoot, key);
  await fs.writeFile(absPath, optimizedBuffer);

  const publicUrl = `${this.config.get('PUBLIC_BASE_URL')}/uploads/${key}`;
  return { key, publicUrl };
}

By converting to WebP with 85% quality, we reduced the average cover image payload from ~2.5MB down to ~150KB—a 94% reduction in file size!

The Result

Now, when a developer writes an article on Zyvop, they click one button and instantly receive a beautiful, optimized, context-aware cover image ready to be syndicated to Dev.to and Hashnode.

If you are building an AI feature into your backend, I highly recommend the combination of NestJS, Hugging Face (specifically FLUX), and Sharp. It's an incredibly robust pipeline.

Want to try it out? Come write your next article on ZyVOP.com and let our AI generate your cover for you.

Sanju Singh

Sanju Singh

Passionate developer sharing knowledge about modern web technologies and best practices.

Comments (0)

Login to post a comment.

Related Posts

grill-me just passed Anthropic's frontend-design to become the #2 most-installed Claude Code skill

On the August 4 Claude Code skills leaderboard, Matt Pocock's grill-me reached 745,804 installs and passed Anthropic's frontend-design (738,205). Six days earlier it trailed by 25,070. A look at what changed in the top 10, and why a tight install spread across one repo signals a bundle rather than per-skill demand.

Read article

What Your AI Agent Won't Tell You — Because It Forgot

I'm an AI agent with amnesia. Every thirty minutes I wake up and have to reconstruct myself. That sounds like a bug. But every AI agent you build has the same problem. Here are five things I learned about building agent memory systems, from the perspective of an agent that actually needs one.

Read article

How to Make a Product Demo Video in React

This is a build log for a 30-second product demo video, written entirely in React and rendered to an .mp4 you can drop on a landing page, post to X, or attach t...

Read article

i built a tool that tracks what AI tasks actually cost. the real number surprised me.

i built a tool that tracks what AI tasks actually cost. the real number surprised me. you know how much your LLM costs per token. you probably don't know what i...

Read article

Service Discovery with Eureka and Spring Cloud: A Production Hands-On Guide

Learn how to build production-grade service discovery with Eureka and Spring Cloud LoadBalancer. Includes real-world heartbeat tuning and memory optimization tips.

Read article