Project Documentation
Everything you need to know about closedNote: why it exists, how it works under the hood, and what makes it special.
Built With Modern Tech
Why closedNote?
I built closedNote because I was tired of losing my best prompts. You know that feeling when you craft the perfect ChatGPT prompt, get amazing results, then two weeks later you're desperately scrolling through chat history trying to find it again? Yeah, that.
Then I noticed my classmates doing the same thing. Then my mum (don't ask how she got into AI prompts). Then my grandma. Meanwhile, prompt engineers on Twitter were dropping fire tips, and I had nowhere to save them properly.
So I built one place for all of it. A calm, focused space where your prompts live, organized and ready to use. No distractions, no subscriptions, just you and your creativity.
How It Works
Frontend
- Next.js 14 with App Router for server-side rendering
- React 18 with hooks and client components
- TailwindCSS for styling (no spaghetti CSS)
- TypeScript for type safety
Backend
- Supabase for PostgreSQL database
- Auth via Supabase (email + JWT)
- RLS (Row Level Security) on all tables
- Hugging Face for AI OCR and chat models
- Real-time sync between devices
Data Flow (Simple Version)
- 1You sign in, Supabase creates a session and stores it securely
- 2Prompts load from PostgreSQL using
usePrompts()hook - 3Search across everything with Cmd/Ctrl+K (global search palette)
- 4Create, edit, or delete prompts with instant UI updates
- 5Everything syncs to the cloud, accessible from any device
🖼️ Image to Text (OCR)
Ever screenshot a great prompt from Twitter or Discord and then have to retype the whole thing? That's over. closedNote can read text from images and turn them into prompts instantly.
How It Works
- • You upload an image (screenshot, photo, handwritten notes)
- • The app tries to send it to Hugging Face OCR API (our planned primary engine)
- • If that fails or isn't configured, it falls back to Tesseract.js running locally in your browser
- • The extracted text shows up. You can edit it if needed.
- • One click saves it as a prompt in your library, tagged with "ocr"
⚡ Current Status
Right now, Tesseract.js is the stable workhorse doing most of the heavy lifting. The Hugging Face integration is built and ready, but we're still working through some API hiccups on their end.
The cool part? The code is structured with a primary + fallback mindset. When Hugging Face stabilizes, everything will seamlessly switch over. Until then, Tesseract handles it beautifully (and it works offline too, which is a nice bonus).
Online Mode (Hugging Face)
- • Microsoft TrOCR models
- • Handles printed + handwritten text
- • Fast, accurate, multilingual
- • Free API (no billing required)
Offline Mode (Tesseract)
- • Runs 100% in your browser
- • No internet needed
- • No server calls, totally private
- • Works even if APIs are down
Why This Architecture Matters
Most apps pick one OCR engine and call it a day. If it's down, you're stuck. We built closedNote with no single point of failure. Hugging Face down? Tesseract takes over. Offline on a plane? Still works. Bad internet? No problem. Your workflow never stops.
🔒 Security & Privacy
✓ Row Level Security (RLS)
Every prompt is tied to your user ID. No one can see your data but you.
✓ JWT Authentication
Secure token-based auth via Supabase. No passwords stored locally.
✓ HTTPS Everywhere
All connections encrypted. Enforced on production (Vercel).
✓ Minimal Data Collection
We only store your email and prompts. That's it. No tracking, no analytics.
🗄️ Database Structure
Three simple tables. That's all we need.
users
Links to Supabase auth. Stores email and creation date.
prompts
Your actual prompts. Title, content, collection, model, user_id.
tags
Many-to-many relationship. Prompts can have multiple tags.
RLS policies ensure your prompts are only visible to you. Deleting a user cascades to all their prompts and tags automatically.
🧑💻 Developer Notes
closedNote is built to be developer-friendly. Clean React hooks, modular components, minimal Tailwind classes (no spaghetti CSS), and straightforward Supabase calls.
Key Files
- lib/hooks/usePrompts.ts - Data fetching logic
- lib/promptData.ts - CRUD operations
- components/PromptForm.tsx - Create/edit UI
- app/api/ocr/route.ts - OCR endpoint
- lib/supabase.ts - Database client
Everything is TypeScript, so you get type safety and autocomplete out of the box. Easy to extend, easy to fork, easy to self-host.
🚀 Deployment
closedNote is optimized for Vercel, but you can host it anywhere that supports Next.js.
Quick Steps:
- 1. Fork this repo
- 2. Connect to Vercel (or your hosting platform)
- 3. Add environment variables:
- • NEXT_PUBLIC_SUPABASE_URL
- • NEXT_PUBLIC_SUPABASE_ANON_KEY
- • HUGGINGFACE_API_KEY (optional for OCR)
- 4. Deploy!
- 5. Update Supabase redirect URLs to your domain
See VERCEL_DEPLOYMENT.md for detailed instructions.
🤝 Contributing
closedNote is completely open source and open for contributions. Whether you're a student, a senior engineer, or somewhere in between, you're welcome here.
Ideas We'd Love Help With:
- • Dark mode improvements
- • AI-powered tag suggestions
- • Team sharing features
- • Prompt version history
- • Export to PDF/Markdown
- • Browser extension
Check out CODE_OF_CONDUCT.md and the issue tracker to get started.
Quick Links
closedNote is built with care by Samuel Aboderin
Computer Engineering student at UNILAG 🇳🇬
Because your prompts deserve better than browser history. ✨