The Problem That Started It All
If you're like me, you've probably got AI prompts scattered across:
- Random text files
- Notion pages
- Apple Notes
- That one Google Doc from 3 months ago
- Slack DMs to yourself
And every time you need to tweak a prompt, you're playing copy-paste gymnastics, losing track of what worked and what didn't.
So I built Prompt Builder - a block-based workspace for composing, organizing, and sharing AI prompts. Think of it as Notion blocks meet prompt engineering.
🎯 What It Does
Instead of managing prompts as walls of text, you build them from draggable blocks:
[Block 1: Context] → [Block 2: Instructions] → [Block 3: Examples] → [Block 4: Output Format]
Each block has its own controls:
- 👁️ Toggle visibility (test variations without deleting)
- 🏷️ Wrap with custom tags
- 🎙️ Voice input with transcription
- 📋 Individual copy/paste/clear
The killer feature? Live preview shows your combined prompt in real-time with character count.
🛠️ The Tech Stack
Here's what powers it:
`// Core Stack
- Next.js 14 (App Router)
- Supabase (Database + Auth)
- Stripe (Payments)
- Tailwind CSS + shadcn/ui
// State Management
- Zustand (Editor state)
- TanStack Query (Server state)
// Key Libraries
- @dnd-kit (Drag & drop)
- react-textarea-autosize (Auto-expanding textareas)
- sonner (Notifications)
- next-themes (Dark mode)`
🏗️ Architecture Decisions
- Block Storage Strategy
I store blocks as JSONB in Supabase for maximum flexibility:
CREATE TABLE prompts ( id UUID PRIMARY KEY, user_id UUID REFERENCES auth.users, name TEXT, blocks JSONB, created_at TIMESTAMPTZ ); - Share Links Without Auth Users can share prompts instantly without signing up. I generate unique IDs with nanoid and store them in a public table:
// Generate shareable link
const shareId = nanoid(10);
await supabase
.from('shared_prompts')
.insert({
id: shareId,
content: blocks,
expires_at: proUser ? expiryDate : null
});
- Real-time Preview Performance Instead of re-rendering everything on each keystroke, I use:
- React.memo on block components
- Debounced preview updates
- Virtualization for long block lists with @tanstack/react-virtual
💡 Cool Features I'm Proud Of
Voice Input with Translation (Pro)
// Simplified implementation
const transcript = await speechToText(audioBlob, sourceLanguage);
const translated = proUser
? await translateText(transcript, targetLanguage)
: transcript;
updateBlockContent(blockId, translated);
Drag & Drop with @dnd-kit
<DndContext onDragEnd={handleDragEnd}>
<SortableContext items={blocks}>
{blocks.map(block => (
<SortableBlock key={block.id} {...block} />
))}
</SortableContext>
</DndContext>
Variables System (Pro)
Users can create reusable templates with variables:
Hello {{name}}, regarding {{topic}}...
📊 Current Status
- ✅ MVP launched at promptbuilder.space
- 🎉 No signup required to test
- 💰 Free tier: 3 prompts, 5 blocks/prompt, 10 share links
- 🚀 Pro unlocks: unlimited everything + exports + custom tags + variables
🤔 Lessons Learned
- Start with sharing: Making sharing work without auth was complex but worth it for adoption
- JSONB is your friend: For flexible content structures, JSONB beats normalized tables
- Preview performance matters: Users expect instant feedback - optimize aggressively
- Stripe is still king: For SaaS billing, nothing beats Stripe's developer experience
🎯 What's Next?
- Team workspaces
- Prompt marketplace
- API access
- Chrome extension
- More AI model integrations
💭 Question for the Community
What features would make YOU switch from your current prompt management solution?
I'm especially curious about:
- Export formats you'd want
- Collaboration features
- Integration needs
Try it out (no signup needed): promptbuilder.space
Drop your thoughts below or roast my implementation choices - I'm here for all of it! 🔥
P.S. - If you're building something similar or want to chat about the technical decisions, my DMs are open!

Top comments (0)