Match your resume to the job—before you apply.
Resume Match is a U.S.-focused SaaS that helps job seekers understand how well their resume aligns with specific job descriptions. Upload your resume PDF, paste a job description, and get an instant analysis: match score, missing keywords, ATS risk flags, stronger bullet rewrites, and a tailored summary.
Resume Match analyzes your resume against a job description and returns:
- Match Score: Overall alignment percentage with job requirements
- Missing Keywords: Specific terms from the job description not found in your resume
- Missing Skills: Required skills that aren't present in your resume
- ATS Risk Flags: Formatting and structure issues that could cause parsing problems
- Weak Bullets → Rewritten: Improved versions of existing resume bullets (no fabrication)
- Tailored Summary: Job-specific summary highlighting your most relevant experience
U.S. job seekers in:
- Software engineering
- Product management
- Data & analytics
- Design
Works best when you have a specific job description to match against.
- Upload your resume (PDF format)
- Paste the job description
- Get your report in seconds with actionable insights
The analysis uses structured AI to extract requirements, compare against your resume, and provide specific, actionable feedback. We never invent achievements or add skills you don't have—everything is grounded in your actual resume content.
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS v4
- Database: Neon Postgres
- Storage: Vercel Blob
- Payments: Stripe Checkout
- Analytics: PostHog (optional)
- Monitoring: Sentry, OpenTelemetry
- AI: OpenAI GPT-5-mini (default), GPT-5 (premium/fallback)
- Node.js 18+
- npm or yarn
- OpenAI API key (required)
- Neon Postgres database (optional, for full functionality)
- Stripe account (optional, for payment testing)
- Clone the repository
git clone <repository-url>
cd resume-match- Install dependencies
npm install- Configure environment variables
cp .env.example .env.localEdit .env.local and set at least:
OPENAI_API_KEY=your_openai_api_key_hereFor full MVP functionality, also configure:
# Stripe (for payments)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_SCAN=price_xxx # one-time $2 per scan
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Database (Neon Postgres)
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
# Analytics (optional)
NEXT_PUBLIC_POSTHOG_KEY=ph_xxx
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
# Server-side capture (Stripe webhook); can use same key as NEXT_PUBLIC_POSTHOG_KEY
# POSTHOG_API_KEY=ph_xxx
# POSTHOG_HOST= # optional- Set up the database (if using Neon)
- Create a Neon project at neon.tech
- Run
schema.sqlin the Neon SQL editor - Copy the connection string to
DATABASE_URLin.env.local
- Run the development server
npm run devOpen http://localhost:3000 in your browser.
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run typecheck- Run TypeScript type checking
This repository uses GitHub Actions for continuous integration.
On every pull request and push to main, the CI workflow automatically:
- Installs dependencies - Uses
npm cifor fast, reliable installs - Runs linter - Checks code quality with ESLint
- Runs typecheck - Validates TypeScript types
- Builds the application - Ensures the Next.js app builds successfully
The CI workflow runs without requiring any secrets or external services. The build step uses default/empty values for optional environment variables (Sentry, app URL) to ensure builds complete successfully.
For enhanced CI functionality, you can optionally configure these secrets in GitHub Settings → Secrets and variables → Actions:
NEXT_PUBLIC_APP_URL- App URL for build-time configuration (defaults tohttp://localhost:3000if not set)SENTRY_ORG- Sentry organization (optional, for source maps)SENTRY_PROJECT- Sentry project (optional, for source maps)
Note: These secrets are optional. CI will run successfully without them.
Before pushing, you can run the same checks locally:
npm run lint # Check code quality
npm run typecheck # Check TypeScript types
npm run build # Verify production build- Push your code to GitHub
- Import the repository in Vercel
- Configure environment variables in Vercel dashboard:
OPENAI_API_KEYDATABASE_URL(if using Neon)STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET,STRIPE_PRICE_SCANNEXT_PUBLIC_APP_URL(your Vercel deployment URL)NEXT_PUBLIC_POSTHOG_KEY,NEXT_PUBLIC_POSTHOG_HOST(if using PostHog);POSTHOG_API_KEYfor server-side conversion capture from Stripe webhook
- Configure Stripe webhook:
- Point webhook URL to
https://your-app.vercel.app/api/webhooks/stripe - Use the webhook secret in
STRIPE_WEBHOOK_SECRET - Set the webhook endpoint to API version
2026-02-25.clover(or your account default) so events match the app.
- Point webhook URL to
All client events include session_id, route, and UTM params. The app identifies by session ID initially; when full app is on and the user verifies email, the client calls alias + identify with the verified identity ID so server-side events (e.g. Stripe webhook) and client events merge into one person in PostHog.
Events: landing_viewed, cta_clicked, sample_report_viewed, resume_uploaded, jd_pasted, scan_started, scan_completed, scan_failed, result_viewed, paywall_viewed, checkout_started, checkout_completed, checkout_failed, premium_unlocked, export_clicked, copy events (summary_copied, bullet_copied, etc.). Lifecycle: verification_email_sent, verification_success, verification_failed (reason: expired | missing | error), usage_check_failed (status), result_missing.
Recommended funnel (full app):
landing_viewed → cta_clicked / sample_report_viewed → verification_email_sent → verification_success → scan_started → scan_completed → result_viewed → paywall_viewed (if not free) → checkout_started → checkout_completed / premium_unlocked
Revenue: Attached to checkout_completed and premium_unlocked (revenue: 2, currency: "USD"). Conversions are also captured server-side from the Stripe webhook (source: "webhook") so payments are counted even if the user never returns from checkout. In PostHog, create a Funnel with the steps above; break down by person (after identity merge) or by UTM for acquisition.
MVP Status: Core functionality implemented
- ✅ Resume PDF upload and extraction
- ✅ Job description input
- ✅ AI-powered analysis (match score, keywords, skills, ATS risks)
- ✅ Bullet rewriting (no fabrication)
- ✅ Tailored summary generation
- ✅ Paywall and Stripe integration
- ✅ Analytics tracking
- ✅ Result page with full report
Roadmap:
- Enhanced ATS parsing accuracy
- Additional vertical support
- Export functionality
- Cover letter generation (premium)
$2 per scan. One free scan, then $2 per report. One-time payment, no subscription.
- Your documents are processed securely
- We don't store resumes after analysis
- We don't share your data with third parties
- We don't use your data for training
- All analysis is grounded in your actual resume—no fabrication
This repository is publicly visible for transparency, feedback, and credibility.
This is not an open-source project. The source code is provided for viewing and evaluation purposes only. See LICENSE for full terms.
If you have feedback, suggestions, or find bugs, please open an issue. However, please understand that this is a commercial product, and contributions may not be accepted.
Copyright (c) 2025 Resume Match. All rights reserved.
This software is proprietary and confidential. Public visibility does not constitute a grant of rights to use, modify, or distribute the software. See LICENSE for full terms.
Important: This repository is made publicly visible for transparency and feedback purposes. It is NOT licensed under MIT, Apache, or any other permissive open-source license. Unauthorized commercial reuse is prohibited.
Resume Match provides analysis and suggestions to help improve your resume. We do not guarantee job interviews, offers, or ATS system compatibility. Results depend on many factors beyond resume quality.