PROJECT 9 COMPLETED

IdeaToImagePrompt

A conversational AI tool that guides you through describing your image idea and generates professional, reusable prompt templates for your chosen image generation platform — using live documentation fetched at the time of generation.

Node.jsExpressGroq LLaMA 3.3-70bClaude HaikuSearXNGCrawl4AISupabaseRailwayResend

Research Question

Can an AI-guided conversation extract enough visual context from a user to generate platform-specific, reusable image prompt templates that outperform what a user would write themselves?

Key Results

Services: 3 application + 2 infrastructure (SearXNG, Crawl4AI)

Platforms supported: Platform independent (any tool with public docs)

Template variations per generation: 4 (Faithful, Cinematic, Stylised, Experimental)

Daily rate limit: 5 generations per user

Auth: Google OAuth via Supabase

Session storage: PostgreSQL (Supabase connection pooler)

Deployment: Railway (6 services)

Primary LLM: Groq LLaMA 3.3-70b (conversation)

Generation LLM: Claude Haiku (structured prompt output)

Build approach: Claude Code autonomous development

Architecture

User Browser │ ▼ Frontend Service (Node/Express) - Google OAuth via Supabase - Session management (PostgreSQL) - Rate limiting (5/day per user) │ ├──► Conversation Engine (Groq LLaMA 3.3-70b) │ │ │ └──► Search Engine (SearXNG + Crawl4AI) │ └── Fetches live tool documentation │ └──► Prompt Generator (Claude Haiku) └── Generates 4 reusable templates as JSON

Case Study

The Problem

Most people who use AI image generation tools struggle with prompts. They know what they want to see but don't know how to describe it in a way the model understands. Generic chatbots like ChatGPT can help — but they give you a one-off prompt based on outdated training data, with no knowledge of the specific tool's current syntax or parameters.

The Approach

IdeaToImagePrompt uses a three-service architecture to solve this:

1. A conversation engine powered by Groq LLaMA 3.3-70b guides the user through 6-8 focused questions about their image — subject, lighting, mood, camera angle, colour palette, texture, and their chosen tool.

2. A search engine microservice (SearXNG + Crawl4AI) fetches live documentation from the official docs of whatever tool the user names — Midjourney, FLUX, ChatGPT Image, Gemini Image, Stable Diffusion, or any other tool with public documentation.

3. A prompt generator powered by Claude Haiku takes the conversation history and live docs and produces 4 reusable template variations: Faithful, Cinematic, Stylised, and Experimental — each with a [SUBJECT] variable so the template works for any subject.

What Makes It Different

  • Platform independent — name any image generation tool and the system fetches its current documentation. Not limited to a hardcoded list.

  • Guided, not open-ended — the conversation collects the 8 dimensions that matter most for image prompts. Users don't need to know what to ask.

  • Reusable templates — every output has a [SUBJECT] variable. One template, infinite images.

  • Live docs — prompts are built from current documentation, not training data that may be months old.


Key Technical Decisions

Groq for conversation — low latency is critical for a chat interface. Groq's llama-3.3-70b-versatile delivers sub-2-second responses which keeps the conversation feeling natural.

Claude Haiku for generation — structured JSON output with 4 template variations requires a model that follows formatting instructions precisely. Haiku handles this reliably with max_tokens set to 4096 to prevent truncation.

SearXNG as the search layer — self-hosted on Railway with a custom Docker image to enable the JSON format endpoint. Crawl4AI handles the actual page crawling with async task-based polling.

Session persistence via PostgreSQL — express-session backed by connect-pg-simple using the Supabase connection pooler. Eliminates the MemoryStore cold session problem that caused auth failures under the proxy.

Challenges

The biggest challenge was deploying the tool as a subpath proxy (balajiloganathan.net/txt2imageprompt) — Cloudflare's 100-second timeout killed long-running LLM calls. The solution was to give the tool its own subdomain (i2ip.balajiloganathan.net) with DNS-only Cloudflare routing, bypassing the proxy entirely.

OAuth session cookies through a reverse proxy required careful configuration — sameSite: none, secure: true, and trust proxy: 1 for Railway's TLS termination. The auth flow was rebuilt to use a server-side /auth/session GET route instead of a cross-origin fetch, so the session cookie is always set on the correct domain.

Key Findings & Learnings

1. Subpath proxying through Cloudflare is not viable for LLM-backed tools — the 100-second timeout kills requests. Dedicated subdomains with DNS-only routing are the correct architecture.

2. express-session MemoryStore fails silently in production under Railway — session data is lost on container restart or when requests route to different instances. PostgreSQL-backed sessions are required from day one.

3. SearXNG on Railway requires a custom Docker image with settings.yml baked in — the JSON format endpoint is disabled by default and cannot be configured via volume mounts on Railway.

4. Live documentation fetching works well for tools with structured docs sites (Midjourney docs.midjourney.com, OpenAI platform.openai.com) but fails for tools that block crawlers or serve JavaScript-rendered content.

5. Claude Haiku generates significantly better structured JSON when max_tokens is set to 4096 — the default causes truncation mid-template which breaks JSON parsing entirely.

6. The [SUBJECT] variable pattern for reusable templates was the most positively received feature in early user testing — users immediately understood the concept of "one template, any subject".

Try IdeaToImagePrompt →

A conversational AI tool that guides you through describing your image idea and ...

Personal technical research experiment. All observations are from controlled testing environments. Not financial advice.
● Live AI Trading
PortfolioLoading…
P&L—
Trades—
Open Dashboard →