A modern Progressive Web App for managing, organizing, and AI-improving reusable prompts with dynamic variables using OpenRouter API.
Pocket Promptsmith is a feature-rich PWA built with Next.js 16 (App Router + React 19) that allows users to save, organize, and enhance reusable prompts with dynamic variables and AI assistance powered by OpenRouter.
π Explore the live application: pocket-promptsmith.vercel.app
- π Email + Password Authentication - Secure login with Supabase Auth
- π Prompt Management - Create, edit, and organize prompts with categories, tags, and a short "Objective" summary
- π€ AI-Powered Improvements - Enhance prompts using OpenRouter API with a premium (5/day) + free fallback model chain and a dedicated "text to improve" field (4k chars) that avoids sending the entire prompt when it's too long
- π’ Dynamic Variables - Extract and replace variables like
{{variable}}in prompts - π± Progressive Web App - Installable app with offline capabilities
- βΏ Freemium Model - 10 prompts limit, 5 AI improvements per day
- β‘ Server-Side Rendering - Optimized with Next.js 16 and Webpack/Turbopack
- π¨ Modern UI - Clean interface with Tailwind CSS and accessibility features
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Quick Start
- Environment Configuration
- Database Setup
- Development
- API Documentation
- Testing
- Deployment
- Security & Performance
- Troubleshooting
- Contributing
- License
| Category | Technology | Version |
|---|---|---|
| Frontend | Next.js | 16.0.1 |
| React | 19.2 | |
| TypeScript | 5.8 | |
| Tailwind CSS | 3.4 | |
| Backend | Supabase | Latest |
| PostgreSQL | Latest | |
| State Management | Zustand | 5.x |
| Forms | React Hook Form | Latest |
| Zod | Latest | |
| AI Integration | OpenRouter API | Latest |
| Testing | Playwright | Latest |
| Vitest | Latest | |
| PWA | Service Worker | Native |
Pocket-Promptsmith/
βββ app/ # Next.js 16 App Router
β βββ layout.tsx # Global metadata + providers
β βββ page.tsx # Public landing page
β βββ login/ # Email + password authentication
β βββ auth/callback/ # Supabase session exchange
β βββ prompts/ # Protected dashboard
β β βββ layout.tsx # Protected layout with daily reset
β β βββ page.tsx # Prompts listing
β β βββ new/ # Create new prompt
β β βββ [id]/ # Prompt details
β β β βββ page.tsx # Edit prompt
β β β βββ use/ # Use prompt modal
β βββ api/ # API routes
β βββ ai-improve/ # OpenRouter AI integration
βββ public/ # Static assets
β βββ manifest.json # PWA manifest
β βββ sw.js # Service worker
β βββ icons/ # App icons
βββ src/
β βββ components/ # Reusable UI components
β β βββ common/ # Generic UI components
β βββ features/ # Feature-based architecture
β β βββ auth/ # Authentication logic
β β βββ prompts/ # Prompt CRUD operations
β β βββ ai-improvements/ # AI integration
β β βββ variables/ # Variable extraction/replacement
β β βββ limits/ # Freemium limits
β β βββ pwa/ # PWA functionality
β βββ lib/ # Core utilities
β β βββ supabaseServer.ts # Server-side Supabase client
β β βββ limits.ts # Business logic limits
β β βββ env.ts # Environment validation
β βββ store/ # Zustand state management
β βββ types/ # TypeScript definitions
β βββ styles/ # Global styles
βββ supabase/ # Database schema & migrations
β βββ schema.sql # Complete database schema
βββ tests/ # Test suites
β βββ unit/ # Vitest unit tests
β βββ integration/ # Playwright E2E tests
βββ proxy.ts # Next.js middleware replacement
βββ next.config.ts # Next.js configuration
βββ tailwind.config.ts # Tailwind CSS configuration
βββ vitest.config.ts # Vitest configuration
βββ playwright.config.ts # Playwright configuration
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher)
- npm or yarn
- Git
- Supabase CLI (optional but recommended)
- Create a Supabase account
- Create a new project
- Note your project reference ID
git clone https://github.com/your-username/pocket-promptsmith.git
cd pocket-promptsmithnpm installcp .env.example .env.localEdit .env.local with your configuration (see Environment Configuration).
# Install Supabase CLI (if not installed)
npm install -g supabase
# Login to Supabase
supabase login
# Link your project
supabase link --project-ref YOUR_PROJECT_REF
# Apply database schema
supabase db pushnpm run devVisit http://localhost:3000 to see the application.
Create a .env.local file in the root directory:
# Supabase Configuration (Required)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
NEXT_PUBLIC_SITE_URL=http://localhost:3000
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# OpenRouter AI Configuration (Required for AI features; env validator requires value)
OPENROUTER_API_KEY=your-openrouter-api-key
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
# Application Configuration
NODE_ENV=developmentSecurity Notes
src/lib/env.tsvalidates with Zod and is server-side only; if keys are missing, the app fails on startup.- Don't import
envinuse clientcomponents; web clients should only depend onNEXT_PUBLIC_*.- For CI/tests you can use dummy values (
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321,NEXT_PUBLIC_SUPABASE_ANON_KEY=anon,OPENROUTER_API_KEY=dummy).- The service role key is used only from CLI for migrations; never share it or deploy it to the frontend.
supabase db pushThis command will create all necessary tables, RLS policies, and PostgreSQL functions:
profiles- User profiles and limits trackingprompts- Prompt storage with metadata; includesai_improvement_source(nullable) to save only the fragment used in AI improvementsprompt_improvements- AI improvement history- PostgreSQL Functions:
get_user_tags()- Fetch user tags efficientlyincrement_prompt_use_count()- Atomic counter updatesreset_daily_improvements()- Daily quota reset (marked asvolatile)
If you prefer manual setup, execute the SQL commands from supabase/schema.sql in your Supabase SQL Editor.
Important: Ensure all SQL functions are applied correctly. If you encounter errors like "UPDATE is not allowed in a non-volatile function", verify that functions modifying data are marked as
volatile(notstable) in PostgreSQL.
| Command | Description |
|---|---|
npm run dev |
Start development server with Turbopack |
npm run build |
Create production build |
npm run start |
Start production server |
npm run lint |
Run ESLint with Next.js configuration |
npm run test |
Run Vitest unit tests |
npm run test:watch |
Run Vitest in watch mode |
npm run test:integration |
Run Playwright E2E tests |
npm run type-check |
Run TypeScript type checking |
npm run build -- --webpack |
Production build using Webpack (useful in environments where Turbopack is restricted) |
- Code Quality:
npm run lintensures clean code with flat config - Testing:
npm run testruns unit tests, ignores Playwright specs - Type Safety: TypeScript strict mode ensures type safety
- Hot Reloading: Turbopack provides fast development experience
Endpoint: POST /api/ai-improve
Authentication: Requires valid Supabase session
Request:
{
content: string;
goal?: string;
category: "Writing" | "Code" | "Marketing" | "Analysis" | "Creativity" | "Education" | "Other";
temperature?: number; // 0..1
length?: "short" | "medium" | "long";
}Response:
{
improved_prompt: string;
changes: string[];
diff: string;
modelUsed?: string;
premiumImprovementsUsedToday: number;
}The backend automatically selects the appropriate model using the getModelsForImprovement helper. The first five daily improvement attempts use premium models (google/gemini-2.5-flash-lite, google/gemini-2.0-flash-lite-001); once those are exhausted the flow falls back to free models (google/gemini-2.0-flash-exp:free, meta-llama/llama-4-maverick:free).
Error Responses:
401 Unauthorized- Invalid or missing session429 Too Many Requests- Daily premium improvement limit exceeded400 Bad Request- Invalid input data
profiles
id(uuid, primary key)email(text)plan('free' | 'pro')prompt_quota_used(integer)improvements_used_today(integer)improvements_reset_at(timestamptz)created_at(timestamptz)updated_at(timestamptz)
prompts
id(uuid, primary key)user_id(uuid, foreign key)title(text)summary(text)content(text)category(enum)tags(text[])is_favorite(boolean)use_count(integer)created_at(timestamptz)updated_at(timestamptz)
prompt_improvements
id(uuid, primary key)prompt_id(uuid, foreign key)user_id(uuid, foreign key)original_content(text)improved_content(text)diff_json(jsonb)created_at(timestamptz)
# Run all unit tests
npm run test
# Run specific test file
npm run test extractVariables
# Watch mode for development
npm run test:watch
# Generate coverage reports (~66% statements)
npm run test:coverageCoverage and environment:
vitest.config.tsinjects dummy values forNEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,OPENROUTER_API_KEYandOPENROUTER_BASE_URL, so you don't need real secrets to run tests.npm run test:coverageuses@vitest/coverage-v8and limits target tosrc/**/*(excluding heavy UI/PWA) to have an actionable report. The result is saved incoverage/index.htmland currently covers 66% of statements.- The new suites cover prompt logic (
tests/unit/promptServices.test.ts), stores (premiumUsageStore,uiStore), AI helpers and environment validators, in addition to existing form, limits, etc. tests.
# Install Playwright browsers once (local only)
npx playwright install --with-deps
# Run E2E tests (Playwright starts Next.js automatically)
npm run test:integrationTest Suites:
auth.spec.ts- Renders email + password form and validates errorsprompts.spec.ts- Ensures dashboard redirects to/loginwithout sessionai.spec.ts- HitsPOST /api/ai-improvewithout session and visits/prompts/newto check savingvariables.spec.ts- Smoke test of landing and variable content
playwright.config.tsdefineswebServerwithnpm run dev -- --hostname 127.0.0.1 --port 3000, so the suite starts and stops Next.js automatically during the pipeline (no need for a parallelnpm run dev). It also sets the same dummy environment values that Vitest uses.
- The
ci.ymlaction runs on every push tomain/masterand on all Pull Requests. - Key steps:
npm ci,npm run lint,npm run test,npm run test:coverage, Playwright browser installation (npx playwright install --with-deps) andnpm run test:integration. - All tasks run on Node 20 on Ubuntu and reuse dummy values for Supabase/OpenRouter, so workflows don't depend on sensitive secrets.
- If you need to inspect coverage reports generated in CI, you can add
actions/upload-artifactpointing tocoverage/(the flow is prepared for it).
This application is currently deployed on Vercel: pocket-promptsmith.vercel.app
-
Connect Repository:
npx vercel --prod
-
Environment Variables: Add all environment variables in Vercel dashboard
-
Database: Ensure
supabase db pushis run on production
Netlify:
- Build command:
npm run build - Publish directory:
.next - Environment variables required
Railway:
- Connect GitHub repository
- Auto-deploys on push
- Environment variables in dashboard
- Environment variables configured
- Database schema applied with
supabase db push - SSL certificate configured
- Error monitoring (Sentry) setup
- Performance monitoring configured
- Database backups enabled
- Row Level Security (RLS): All Supabase tables protected
- Session Validation: API routes validate Supabase sessions
- CSP Headers: Content Security Policy implementation
- Input Validation: Zod schema validation on all inputs
- Rate Limiting: API endpoints protected from abuse
- Server Components: Leveraging Next.js 16 Server Components
- Caching:
use cachedirective for optimal data fetching - Bundle Optimization: Turbopack for fast builds
- Image Optimization: Next.js Image component
- Service Worker: PWA caching strategies
- Local Storage: Minimal data stored locally
- Session Management: Secure cookie-based sessions
- API Key Protection: OpenRouter keys never exposed to client
- GDPR Compliance: User data deletion capabilities
Problem: PostgreSQL function volatility issue Solution:
-- Ensure functions modifying data are marked as volatile
CREATE OR REPLACE FUNCTION reset_daily_improvements(target_user_id uuid)
RETURNS public.profiles
LANGUAGE sql
VOLATILE -- Not STABLE
AS $$
-- function body
$$;Problem: Development environment restrictions Solution: Run build outside restricted sandbox environment
Problem: Incorrect Supabase URL configuration Solution:
- Verify
NEXT_PUBLIC_SUPABASE_URLformat:https://project-id.supabase.co - Check redirect URLs in Supabase dashboard
- Ensure
NEXT_PUBLIC_SITE_URLmatches your domain
Problem: OpenRouter API issues Solution:
- Verify
OPENROUTER_API_KEYis valid - Check API quotas and limits
- Ensure network connectivity to OpenRouter
Problem: Service Worker registration issues Solution:
- Check browser console for SW errors
- Verify
manifest.jsonis accessible - Ensure HTTPS in production
Enable debug logging:
NODE_ENV=development npm run dev- Server logs: Terminal output during development
- Browser logs: Developer console for client-side debugging
- Supabase logs: Dashboard > Logs section
We welcome contributions! Please follow these guidelines:
- Fork repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
npm run test && npm run lint - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- TypeScript: Strict mode enabled
- ESLint: Flat config with Next.js recommended rules
- Prettier: Code formatting (run
npm run format) - Conventional Commits: Use semantic commit messages
- Title: Clear and descriptive
- Description: Explain what, why, and how
- Tests: Include tests for new functionality
- Documentation: Update README if needed
- Breaking Changes: Clearly document and justify
When reporting issues, include:
- Environment: OS, Node version, browser
- Reproduction steps: Clear steps to reproduce
- Expected vs actual behavior
- Screenshots: If relevant
- Error logs: Console output and stack traces
This project is licensed under the MIT License - see the LICENSE file for details.
- β Commercial use - You can use this project commercially
- β Modification - You can modify the project
- β Distribution - You can distribute the project
- β Private use - You can use the project privately
- β Liability - Liability is not granted
- β Warranty - Warranty is not granted
- Next.js Team - For the amazing React framework
- Supabase Team - For the fantastic Backend-as-a-Service
- OpenRouter - For providing accessible AI models
- Tailwind CSS - For the utility-first CSS framework
- Open Source Community - For all the amazing tools and libraries
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with β€οΈ using Next.js, Supabase, and OpenRouter