A transparent, public leaderboard showcasing iOS app revenues powered by RevenueCat. Track and compare MRR (Monthly Recurring Revenue) and revenue metrics from verified apps.
- π Public Leaderboard - Rank apps by MRR or 28-day revenue
- β Verified Metrics - Data directly from RevenueCat API
- π Secure - API keys encrypted with AES-256-GCM
- π Auto-Updates - Daily metric refresh via cron jobs
- π Dark Mode - Beautiful UI with light/dark themes
- π± Responsive - Optimized for all devices
- β‘ Fast - Built with Astro for optimal performance
- Node.js 18+
- PostgreSQL (local) or Supabase account (production)
- RevenueCat account with API access
- Clone the repository
git clone https://github.com/GonzaloFuentes28/AppMRR.git
cd appmrr- Install dependencies
npm install- Set up environment variables
cp .env.example .envGenerate an encryption key:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Add it to your .env file.
- Set up the database
For local development with PostgreSQL:
./setup-local.shOr manually:
createdb appmrr
psql appmrr < schema.sql- Start the development server
npm run devVisit http://localhost:4321 π
- Framework: Astro - Fast, content-focused web framework
- Language: TypeScript
- Database: PostgreSQL / Supabase
- Deployment: Vercel
- API: RevenueCat API v2
- Styling: CSS with design tokens (OKLCH color space)
- Icons: Lucide
appmrr/
βββ src/
β βββ components/ # Reusable Astro components
β β βββ Header.astro
β β βββ LeaderboardTable.astro
β β βββ AddAppModal.astro
β β βββ ...
β βββ layouts/
β β βββ Layout.astro # Main page layout
β βββ lib/ # Utilities and business logic
β β βββ db.ts # Database queries
β β βββ encryption.ts # API key encryption
β β βββ revenuecat.ts # RevenueCat API client
β β βββ validation.ts # Input validation
β βββ pages/
β β βββ index.astro # Leaderboard page
β β βββ api/ # API endpoints
β βββ scripts/ # Client-side TypeScript
β β βββ theme.ts # Dark mode toggle
β β βββ modal.ts # Modal interactions
β β βββ ...
β βββ styles/
β βββ globals.css # Global CSS variables
βββ public/ # Static assets
βββ schema.sql # Database schema
βββ supabase-rls-policies.sql
βββ vercel.json # Vercel config (cron jobs)
AppMRR takes security seriously:
- Algorithm: AES-256-GCM (Galois/Counter Mode)
- Key Derivation: PBKDF2 with 100,000 iterations
- Salt: 64-byte random salt per encrypted value
- Storage: API keys never stored in plaintext
- Endpoint:
/api/add-startup - Limit: 3 requests per hour per IP
- Protection: Prevents spam and abuse
- All inputs sanitized and validated
- SSRF protection for URLs
- SQL injection prevention
- XSS protection
For detailed security information, see SECURITY.md.
Create a .env file with the following variables:
# Required: Encryption key for API keys
ENCRYPTION_KEY=your-64-char-hex-string
# Database (choose one)
# For Supabase:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# For local PostgreSQL:
POSTGRES_URL=postgresql://postgres:password@localhost:5432/appmrr
# Optional: Cron job protection
CRON_SECRET=your-random-secretWhen a user adds their app:
- User Input: User provides their RevenueCat API key (read-only)
- Validation: Key is validated by fetching metrics from RevenueCat
- Encryption Process:
- Generate random 64-byte salt
- Derive encryption key using PBKDF2 (100,000 iterations)
- Generate random 16-byte IV (initialization vector)
- Encrypt with AES-256-GCM
- Generate authentication tag
- Store:
salt:iv:tag:encrypted_data
- Storage: Encrypted string stored in database
- Decryption: Only happens server-side during cron job updates
Security Properties:
- β Each encryption uses unique salt and IV
- β Authentication tag prevents tampering
- β Keys never exposed in API responses
- β Forward secrecy (changing ENCRYPTION_KEY invalidates all keys)
- User submits app information and RevenueCat credentials
- API validates the credentials by fetching metrics
- API key is encrypted and stored securely
- Initial metrics are fetched and stored
- App appears on the leaderboard
A Vercel Cron Job runs daily at midnight UTC:
- Fetches all encrypted API keys from database
- Decrypts each key (server-side only)
- Fetches latest metrics from RevenueCat API
- Updates metrics in database
- Leaderboard automatically reflects new data
We welcome contributions! Here's how to get started:
- Fork the repository
- Clone your fork:
git clone https://github.com/GonzaloFuentes28/AppMRR.git - Create a branch:
git checkout -b feature/your-feature - Install dependencies:
npm install - Make your changes
- Test locally:
npm run dev - Build to verify:
npm run build - Commit your changes:
git commit -m "feat: add amazing feature" - Push to your fork:
git push origin feature/your-feature - Open a Pull Request
- TypeScript: Use explicit types
- Components: Add header comments explaining purpose
- Formatting: Follow existing code style
- Commits: Use conventional commits (feat, fix, docs, etc.)
- π Internationalization - Add support for more languages
- π Analytics - Enhanced metrics and charts
- π¨ UI/UX - Improve design and user experience
- π Security - Additional security measures
- π± Features - New functionality and improvements
- π Documentation - Improve docs and examples
- π Bug Fixes - Find and fix bugs
Add a new app to the leaderboard.
Request Body:
{
"name": "My Awesome App",
"appStoreId": "1234567890",
"websiteUrl": "https://myapp.com",
"founderUsername": "johndoe",
"projectId": "revenuecat-project-id",
"revenuecatApiKey": "sk_xxxxxxxxxxxxx"
}Response:
{
"success": true,
"startup": {
"id": 1,
"name": "My Awesome App"
}
}Cron endpoint for updating metrics (protected by CRON_SECRET).
- Push to GitHub
git add .
git commit -m "Initial commit"
git push origin main-
Import to Vercel
- Go to vercel.com
- Click "New Project"
- Import your repository
- Configure environment variables:
ENCRYPTION_KEYSUPABASE_URLSUPABASE_SERVICE_ROLE_KEYCRON_SECRET
-
Deploy!
The cron job will automatically run daily at midnight UTC.
- Create a Supabase project
- Run
schema.sqlin SQL Editor - Copy your project URL and service role key
- Add to Vercel environment variables
MIT License - see LICENSE for details.
- Inspired by TrustMRR
- Built with Astro
- Powered by RevenueCat
Have questions or suggestions? Open an issue or reach out!
Made with β€οΈ by the indie app community
β Star this repo if you find it useful!