Imaginify: AI Image Studio
Imaginify is a Next.js 14 SaaS that puts professional-grade AI image editing in everyone's hands. By orchestrating Clerk authentication, Cloudinary AI, Stripe payments, and MongoDB, it delivers a complete product experience—not just a tech demo.
The Opportunity
AI-powered image editing used to require expensive software licenses or deep machine learning expertise. Imaginify proves you can build a competitive SaaS by composing best-in-class services, letting you focus on product experience instead of infrastructure.
What It Does
🎨 AI-Powered Transformations
- Restore – Enhance and repair damaged or low-quality images
- Remove Background – Intelligent subject isolation with one click
- Generative Fill – Expand images beyond their original boundaries
- Object Remove – Erase unwanted elements seamlessly
- Recolor – Change object colors with AI-guided precision
💳 Credit-Based Economy
- Usage-based pricing powered by Stripe Checkout
- Transparent credit consumption per transformation
- Secure payment processing with webhook integration
- Real-time balance updates
🔐 Enterprise-Ready Auth
- Clerk handles authentication and user management
- Automatic profile sync via webhooks
- Session management and protected routes
- Social login support
Technical Architecture
The Modern SaaS Stack
- Next.js 14 App Router – Server actions replace traditional API routes
- Clerk – Authentication, user management, and session handling
- Cloudinary – AI transformations and media intelligence
- MongoDB + Prisma – Data persistence with type-safe queries
- Stripe – Payment processing and subscription management
- Zod – Runtime validation for forms and API responses
How It Works
Authentication Flow
The authMiddleware makes every route private except landing pages and webhooks. Unauthenticated visitors are redirected to Clerk's hosted screens. When users sign up, a Clerk webhook mirrors their profile to MongoDB and stores the database ID in Clerk's public metadata for fast lookups.
Transformation Pipeline
Users upload images via Cloudinary's widget, select a transformation type, and configure parameters through a debounced form. When they hit transform, the app:
- Consumes credits from their balance
- Generates a signed Cloudinary URL with AI transformation parameters
- Persists the result to MongoDB with metadata
- Displays the before/after comparison
Billing Integration
Stripe Checkout sessions embed credit package metadata. When payment succeeds, the webhook creates a Transaction document and updates the user's credit balance atomically.
Everything funnels through typed server actions—you get optimistic UI updates without hand-rolling API routes for every mutation.
Code Highlights
Transformation Workflow
The core transformation logic debounces form updates, merges Cloudinary configs, and persists results:
// components/shared/TransformationForm.tsx
const onTransformHandler = async () => {
setIsTransforming(true)
setTransformationConfig(
deepMergeObjects(newTransformation, transformationConfig)
)
setNewTransformation(null)
startTransition(async () => {
await updateCredits(userId, creditFee)
})
}
Once the config settles, we generate a signed Cloudinary URL and persist the transformation:
const imageData = {
title: values.title,
publicId: image?.publicId,
transformationType: type,
width: image?.width,
height: image?.height,
config: transformationConfig,
secureURL: image?.secureURL,
transformationURL: transformationUrl,
aspectRatio: values.aspectRatio,
prompt: values.prompt,
color: values.color,
}
Database Connection Singleton
Mongoose connections are cached in the serverless environment:
// lib/database/mongoose.ts
let cached = global.mongoose || { conn: null, promise: null }
export const connectToDatabase = async () => {
if (cached.conn) return cached.conn
if (!cached.promise) {
cached.promise = mongoose.connect(MONGODB_URL, {
dbName: 'imaginify',
bufferCommands: false,
})
}
cached.conn = await cached.promise
return cached.conn
}
Demo
Impact & Learnings
What This Project Demonstrates:
✅ Service orchestration beats custom ML – Cloudinary's AI is production-ready out of the box
✅ Server actions simplify SaaS – No API layer needed for most mutations
✅ Webhooks enable real-time sync – Clerk and Stripe events keep data consistent
✅ Credit systems work – Usage-based pricing is straightforward with proper state management
Key Takeaways:
- Managed services accelerate shipping – Clerk + Cloudinary + Stripe = weeks saved
- Type safety end-to-end – Prisma + Zod + TypeScript catch bugs before production
- Server actions are perfect for SaaS – Co-located logic with automatic revalidation
- Webhook-driven architecture scales – Async event handling keeps the app responsive
This architecture transfers directly to any AI-powered SaaS: document processing, video editing, audio enhancement, or content generation. The patterns here—typed server actions, webhook-driven sync, and declarative transformations—are production-ready and battle-tested.