A note-taking web app with authentication, tagging, and search — built to strengthen my understanding of fullstack auth flows and database security using Next.js and Supabase. Written by Joel Odum.
I wanted a project that went beyond basic CRUD and actually forced me to understand how authentication and authorization work end to end — not just "add a login form," but how a database enforces who can see what data, even if someone tries to bypass the frontend entirely. This project uses Supabase's Row Level Security (RLS) to make sure every user can only ever access their own notes, at the database level, not just in the UI. Building it also gave me hands-on practice debugging real permission and auth issues (RLS policies, Postgres grants, email confirmation flows) rather than just reading about them.
- Email/password authentication (sign up, log in, log out)
- Create, edit, and delete personal notes
- Tag notes and filter by tag
- Search notes by title or content
- Row Level Security ensures users can only ever access their own notes
- Custom "ink and paper" visual design — masonry note grid, torn-paper card edges, serif display type
- Next.js (App Router)
- Supabase — Postgres database + built-in authentication
- Tailwind CSS for styling
- Deployed on Vercel
-
Clone the repo:
git clone https://github.com/joelgreyhat1/note-manager.git cd note-manager -
Install dependencies:
npm install
-
Create a
.env.localfile in the root directory with your Supabase credentials:NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key -
Run the development server:
npm run dev
-
Open http://localhost:3000 in your browser.
- How Row Level Security policies work in Postgres, and why table-level grants and RLS are two separate layers of access control
- How to structure a Next.js App Router project with separate client/server Supabase clients
- Debugging real permission errors (like
42501: permission denied) instead of just following a tutorial - Designing a UI with actual visual intention rather than defaulting to generic component styling
MIT