Your personal X bookmark manager. Save tweets, organize with folders, read later.
Twitmark is a premium personal bookmark manager for X (Twitter) content, designed for power users who find native X bookmarking system cluttered and hard to navigate. It focuses on:
- Organization - Smart folder system for structured curation with color coding
- Intentionality - Reading List feature for "read-it-later" workflow
- Visual Experience - Clean, glassmorphic design with smooth animations
- Simplicity - Paste X link, save, done. No scraping, no clutter.
- Next.js 16.1.6 - App Router with Edge Runtime support
- Turbopack - Lightning-fast bundler
- TypeScript 5.x - Strict mode enabled
- Node.js 20+ - Compatible with Cloudflare Pages
- Tailwind CSS 4.x - Zero-runtime CSS-in-JS with custom design system
- Shadcn/UI - Beautiful, accessible component library
- Framer Motion 12.29.2 - Smooth animations and micro-interactions
- Lucide React 0.563.0 - Premium icon set
- Magic UI Components - Custom bento grids and aurora effects
- Supabase - PostgreSQL database with built-in authentication
- Supabase Auth - Google OAuth provider with secure session management
- Zod 4.3.6 - Schema-based validation
- react-tweet 3.3.0 - Optimized tweet rendering for Next.js 16
- @cloudflare/next-on-pages - Cloudflare Pages adapter for Next.js
- ESLint 9+ - Code quality and consistency
- Vitest - Unit testing framework
- Playwright - E2E UI testing
twitmark/
├── .docs/ # Documentation
│ ├── architecture.md # System architecture
│ ├── design-system.md # UI/UX guidelines
│ ├── spec.md # Functional requirements
│ ├── tech-stack.md # Technology choices
│ ├── testing-plan.md # Testing strategy
│ ├── performance.md # Performance optimization
│ ├── deployment.md # Cloudflare Pages deployment guide
│ ├── mcp-tools.md # MCP server documentation
│ └── database.md # Database setup
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── actions/ # Server Actions
│ │ │ ├── bookmarks.ts # Bookmark operations
│ │ │ └── folders.ts # Folder operations
│ │ ├── auth/ # Auth routes
│ │ │ └── callback/ # OAuth callback handler
│ │ ├── dashboard/ # Dashboard pages
│ │ │ ├── layout.tsx # Dashboard shell
│ │ │ └── page.tsx # Main dashboard
│ │ ├── globals.css # Tailwind + custom utilities
│ │ ├── layout.tsx # Root layout with dark mode
│ │ ├── login/ # Login page
│ │ └── page.tsx # Landing page
│ ├── components/
│ │ ├── dashboard/ # Dashboard components
│ │ │ ├── add-bookmark-modal.tsx
│ │ │ ├── add-folder-modal.tsx
│ │ │ ├── bookmark-card.tsx
│ │ │ ├── edit-folder-modal.tsx
│ │ │ ├── header.tsx # Dashboard header (navbar)
│ │ │ ├── manage-folders-modal.tsx
│ │ │ └── sidebar.tsx # Full-height navigation sidebar
│ │ ├── ui/ # Base UI components
│ │ │ ├── aurora-background.tsx
│ │ │ ├── bento-grid.tsx
│ │ │ ├── confirm-modal.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── mobile-menu.tsx
│ │ │ └── toast.tsx
│ │ ├── navbar.tsx # Public site navigation
│ │ └── testimonials-marquee.tsx
│ ├── contexts/ # React contexts
│ │ └── folder-context.tsx
│ ├── lib/ # Utility functions
│ │ ├── supabase/
│ │ │ ├── database.ts # Database operations
│ │ │ ├── server.ts # Supabase server client
│ │ │ └── client.ts # Supabase client client
│ │ └── utils.ts # General utilities
│ └── types/ # TypeScript types
│ └── index.ts
├── .clinerules # AI development behavior
├── TODO.md # MVP roadmap & progress
├── context.md # Project context & memory
├── supabase/ # Supabase configuration
│ └── schema.sql # SQL schema for setup
└── package.json
- Node.js 20+ LTS
- npm, yarn, pnpm, or bun
- Supabase account (free tier works)
# Clone repository
git clone https://github.com/tinodau/twitmark.git
cd twitmark
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your Supabase credentials
# Start development server
npm run devOpen http://localhost:3000 in your browser.
# Build with Cloudflare Pages adapter
npx @cloudflare/next-on-pages@1
# Or regular Next.js build
npm run build
npm startTwitmark is deployed on Cloudflare Pages with Edge Runtime support.
-
Create Supabase project:
- Single
twitmarkproject used for both development and production
- Single
-
Run migrations on the project (see
.docs/database.md) -
Configure Cloudflare Pages:
- Build command:
npx @cloudflare/next-on-pages@1 - Build directory:
.vercel/output/static - Add production environment variables:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
- Build command:
-
Deploy: Push to
mainbranch and Cloudflare auto-deploys
Full deployment guide: See .docs/deployment.md
- Save tweets - Paste any X/Twitter URL to save
- Folder organization - Create color-coded folders for categorization
- Reading List - Mark tweets to read later with visual indicator
- Quick actions - Delete, move, or toggle reading status on hover
- Full-height sidebar - Navigation sidebar spans entire viewport height
- Collapsible sidebar - Desktop users can expand/collapse sidebar for more content space
- Responsive design - Works on desktop, tablet, and mobile
- Logo in sidebar - Clean branding integrated into navigation
- Smart header - Navbar only fills remaining width after sidebar
- Real-time updates - Instant feedback on all actions
- Folder filtering - View bookmarks by folder
- Reading List view - Dedicated view for to-read items
- Google OAuth - Secure sign-in with Google account
- Protected routes - Dashboard requires authentication
- Session management - Automatic token refresh
Copy .env.example to .env.local and fill in your Supabase credentials:
# Supabase Project (shared for dev and prod)
NEXT_PUBLIC_SUPABASE_URL="https://your-project.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="your-anon-key-here"Set these in Cloudflare Dashboard → Workers & Pages → Settings → Environment Variables → Production:
# Supabase Project (same as local development)
NEXT_PUBLIC_SUPABASE_URL="https://your-project.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="your-anon-key-here"Detailed setup: See .docs/deployment.md for complete Supabase project setup.
MIT License - see LICENSE file for details