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)