This page was last updated on: 31st May 2025

DO NOT upgrade any dependencies in your package.json for the core stack dependencies (Clerk, Convex, Polar.sh, etc.), unless you have a specific reason to and are following the official migration guides from each service. Upgrading packages without proper migration can break your authentication, database connections, and other critical functionality. The current versions in the boilerplate are tested and stable together.

Repo: https://github.com/ObaidUr-Rahmaan/kaizen

Pre-requisites

  1. Frontend Knowledge (Have completed the Frontend section of the Software Engineer Roadmap) so that your base HTML, CSS, JS and React skills are up to par.
  2. Fundamental Backend Systems Knowledge (Have completed the Systems Expert Fundamentals Course of the Software Engineer Roadmap)
  3. Fundamental Tech Stack Knowledge (Have completed the Kaizen Tech Stack Tutorial)

Tech Stack

  • React Router v7 - Modern full-stack React framework with SSR
  • Convex - Real-time database and serverless functions
  • Clerk - Authentication as a Service Provider
  • Polar.sh - Subscription billing and payments
  • OpenAI - AI chat capabilities
  • Vercel - Deployments without worrying about infrastructure (Auto-Scaling, DDoS protection, etc.)

Cost of running this stack

All of the above services have generous free tiers.

Even as your product grows, the cost remains minimal (averaging $200-300/month with 10,000+ DAUs for 80%+ profit margin).

These 3rd party services abstract away significant infrastructure work in key areas (authentication, database, payments, etc.), letting you focus solely on building your product.

Testing Locally Guide

This guide will walk you through setting up the project for local development and testing.

Date: June 2025

Prerequisites

  • Node.js (v18 or later)
  • npm
  • ngrok or similar tunnel service (for testing webhooks)

Step 1: Installation

  1. Clone the repository and install dependencies:
git clone <repository-url>
cd <repository-name>
npm install --legacy-peer-deps --force

Note: We use --legacy-peer-deps because some packages might have React 18 peer dependencies while we’re using React 19.

Step 2: Set Up Convex

  1. Open a new terminal and run:
npx convex dev
  1. If not logged in, follow the prompts to log in
  2. Create a new project when prompted
  3. This will automatically add your Convex URL to .env.local

Step 3: Set Up Clerk

  1. Go to Clerk Dashboard
  2. Create a new application
  3. Select “React Router” as your framework
  4. Enable Email/Password and Google authentication methods
  5. Go to API Keys and copy them to your .env.local:
VITE_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

Step 4: Configure Clerk-Convex Integration

  1. In Clerk Dashboard:

    • Go to JWT Templates
    • Create a new template
    • Select “Convex”
    • Save the template
  2. Copy the Issuer URL from Clerk

  3. In Convex Dashboard:

    • Go to Settings > Environment Variables
    • Add VITE_CLERK_FRONTEND_API_URL and set it to the Issuer URL from Clerk

Step 5: Set Up Polar (Payments)

  1. Go to sandbox.polar.sh

  2. Create a new organization

  3. Create a subscription plan

  4. Get your API keys from Settings

  5. In Convex Dashboard, add these environment variables:

POLAR_ACCESS_TOKEN=<your-access-token>
POLAR_ORGANIZATION_ID=<your-org-id>
POLAR_WEBHOOK_SECRET=<your-webhook-secret>

Step 6: Configure Webhooks

  1. Get your Convex HTTP URL from the Convex dashboard
  2. In Polar Dashboard:
    • Go to Webhooks
    • Add a new endpoint: <your-convex-http-url>/payments/webhook
    • Select “Format as raw”
    • Generate a new secret
    • Select all event types
    • Click Create

Step 7: Set Up Tunnel for Local Testing

Since Polar needs to reach your local environment for webhooks, set up a tunnel:

  1. Start your tunnel:
ngrok http 5173
  1. Copy the HTTPS URL provided by ngrok

  2. Add it to your Convex environment variables:

FRONTEND_URL=<your-ngrok-url>
  1. Update vite.config.ts to allow the ngrok domain:
server: {
  host: true,
  allowedHosts: ['your-ngrok-subdomain.ngrok.io']
}

Step 8: Start the Development Server

  1. In one terminal, keep Convex running:
npx convex dev
  1. In another terminal, start the frontend:
npm run dev

Your app should now be running at http://localhost:5173 and accessible via your ngrok URL for webhook testing.

Environment Variables Summary

Here’s a complete list of environment variables needed:

# Company & Email Configuration
COMPANY_NAME="Your Company Name"
DEFAULT_FROM_EMAIL="noreply@yourdomain.com"

# Frontend Configuration
FRONTEND_URL="http://localhost:5173"

# OpenAI
OPENAI_API_KEY="sk-..."

# Clerk
VITE_CLERK_PUBLISHABLE_KEY="pk_test_..."
CLERK_SECRET_KEY="sk_test_..."

# Convex
CONVEX_DEPLOYMENT="..."
CONVEX_URL="..."

# Polar
POLAR_ACCESS_TOKEN="..."
POLAR_ORGANIZATION_ID="..."
POLAR_WEBHOOK_SECRET="..."

# Resend
RESEND_API_KEY="re_..."

Testing the Setup

  1. Visit your local URL
  2. Try logging in with Clerk
  3. Test the subscription flow with Polar’s test card:
    • Card number: 4242 4242 4242 4242
    • Any future expiry date
    • Any CVC
    • Any billing information

Troubleshooting

  • If you see “No address provided to convex react client”, check your environment variables
  • If Polar webhooks aren’t working, ensure your ngrok URL is correct and the webhook is properly configured
  • If you get React version conflicts, make sure you used --legacy-peer-deps during installation

Building with Kaizen

1

Prerequisites

  1. Install the latest stable version of Node.js (If you already have Node.js installed, this will override it):

    • Mac/Linux: Install via nvm:
      nvm install stable
      

    Verify Node.js is installed:

    node -v
    

    Should return something like v24.x.y (at the time of writing: 24.1.0)

  2. Create a new empty GitHub repository for your project

    Have the SSH repository URL ready (e.g., git@github.com:username/repo-name.git)

    Make sure it’s the SSH URL, not the HTTPS URL!

  3. Gather your Development API keys from the following services:

If you have your own agency and you’re building for a client, you’ll need to create all the below accounts for them using your own agency company email account and then transfer ownership to them later when the contract ends.

See the Account Management Guide for more information on how to do this.

  • Clerk (Authentication)

    • Create an account at Clerk (or new ‘Application’ if you already have an account)
    • Create a new Application and select all the different sign in methods you’d like to support (Google, Apple, Email, etc.)
    • Copy your VITE_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY from the ‘API Keys’ section.
    • Add them to somewhere safe (ideally if you’re using a clipboard manager, you’ll be able to paste them into your .env file later)

    We’ll get to the CLERK_WEBHOOK_SECRET when we’re testing the app locally and deploying to production. Leave it blank for now.

  • Convex (Database)

    • Create an account at Convex
    • Create a new project
    • Copy your VITE_CONVEX_URL from the project dashboard
    • Add it to somewhere safe (ideally if you’re using a clipboard manager, you’ll be able to paste it into your .env file later)
  • Polar.sh (Subscriptions)

    • Create an account at Polar.sh
    • Create a new organization
    • Copy your POLAR_SECRET_KEY from the API Keys section
    • Add it to somewhere safe (ideally if you’re using a clipboard manager, you’ll be able to paste it into your .env file later)

We’ll get to the POLAR_WEBHOOK_SECRET when we’re testing the app locally and deploying to production. Leave it blank for now.

  • OpenAI (AI Chat)
    • Create an account at OpenAI
    • Generate an API key from the API Keys section
    • Copy your OPENAI_API_KEY
    • Add it to somewhere safe (ideally if you’re using a clipboard manager, you’ll be able to paste it into your .env file later)
2

Setup via CLI

  1. Using your previously saved info (GitHub repo URL and API keys), create your project locally by running:
    npm create @kaizen/app@latest
    

You’ll be given the option to add your API keys during the setup process, or manually later in your .env file.

  1. Follow the prompts to configure your project. The CLI will:
    1. Clone the project template
    2. Create the .env file with all the required environment variables

Done! Your project is now set up:

  • Pushed to your GitHub repo ✅
  • Ready for local development ✅

Make sure to add all of the above API keys to your .env file before you start local development.

3

Developing your app locally

Run your app locally

npm run dev

Setup ngrok

When we run the app later, all requests will be forwarded to ngrok and then to your local app. ngrok is necessary for the auth and subscription webhooks to work.

It’s also best to use either incognito (to prevent any extensions from interfering with the app) or a new browser profile OR Sizzy (Paid), as it allows extensive testing across different devices.

  1. Install ngrok (if you don’t have it already):
    • Install via Homebrew: brew install ngrok
  2. Run your dev server:
    npm run dev
    
  3. Open a new terminal (outside of your editor) and run ngrok http 5173
  4. Copy the ngrok URL.
  5. Update the FRONTEND_URL environment variable in your .env file to the ngrok URL.

This will be your local development URL (e.g. https://1234567890.ngrok-free.app)

The reason we need this is to expose our localhost to the public internet, so that we can setup Clerk and Polar.sh webhooks (which will both send requests to our app in order for us to store those details in our database).

We need to also have the webhooks configured for both Clerk and Polar.sh so we can test the authentication and subscription flows locally.

For Clerk:

  • go to Configure -> Webhooks -> + Add Endpoint
  • Set the Endpoint URL to https://[your-ngrok-url]/api/auth/webhook
  • Set the Events to user.created and user.updated
  • Click Create
  • Copy the webhook secret for your environment variables and update the CLERK_WEBHOOK_SECRET in your .env file.

For Polar.sh:

  • Go to your organization settings -> Webhooks
  • Add a new webhook endpoint: https://[your-ngrok-url]/api/polar/webhook
  • Select the events you want to listen to (subscription events)
  • Copy the webhook secret and update the POLAR_WEBHOOK_SECRET in your .env file.

Important: When returning to work on your project

Each time you restart ngrok, it generates a new URL. You must:

  1. Update the FRONTEND_URL in your .env file with the new ngrok URL
  2. Update your webhook endpoints in:
    • Clerk Dashboard: Go to Webhooks and update the endpoint URL. Then update the CLERK_WEBHOOK_SECRET in your .env file.
    • Stripe CLI command: Run stripe listen --forward-to [the-new-ngrok-url]/api/payments/webhook in a new terminal (outside of Cursor) and copy the webhook secret in the terminal and update the STRIPE_WEBHOOK_SECRET in your .env file.
  3. Restart your dev server after updating the .env file

Failing to update these will cause authentication and payment webhooks to fail silently!

Configure your app components in order

Your app requires several components to be set up in the correct order:

  1. First, set up your Database - See the Database Guide for setting up all your tables

  2. Next, configure Authentication - See the Authentication Guide to set up Clerk authentication

  3. Next, set up Payments - See the Payments Guide to configure Stripe payments and Dispute prevention with ByeDispute / Chargeblast

  4. Next, set up Emails - See the Email Guide to configure Plunk emails

  5. Next, set up User Analytics - See the Analytics Guide to configure DataFast (Optional for now as this is paid only)

  6. Next, set up User Feedback - See the Feedback Guide to configure UserJot

  7. Finally, set up Customer Support - See the Customer Support Guide to configure GetFernand

You must follow this order because your payments system depends on authenticated users, which in turn depend on properly configured database tables.

Done. Your app will now be able to receive webhooks from both Clerk and Stripe.

Remember to always use the ngrok url when testing locally (not localhost:3000)

4

Building the Product

At this point, you should have a clean and beautiful landing page that explains the product and what it does (perhaps with a waitlist setup with Clerk)

But it’s up to you to now add the main functionality of your product (perhaps a Dashboard that users get redirected to after signing up, and all other relevant pages)

We’ve got a dedicated guide page related to building clean and beautiful UIs very quickly: Rapid UI Prototyping

See the ‘The v0 + Cursor Workflow (Recommended)’ section

5

Deploying the App to Production

You’ll need to purchase a domain before deploying to production. Services like Clerk and Stripe require a verified domain for production environments. Purchase a domain from providers like Namecheap, Porkbun, GoDaddy, or Google Domains before proceeding with production deployment.

When you’re ready to deploy your application to production, follow our comprehensive deployment guide:

Deploy to Production Guide

The guide covers everything you need for a successful production deployment:

  • Domain purchase and setup
  • Production database configuration
  • Production authentication setup
  • Production payments setup
  • Vercel deployment
  • Post-deployment verification
6

Setup Analytics

Track your site visitors and get insights on how they interact with your site.

  1. Create an account at DataFast
  2. Copy the Tracking code and paste it into the head of your index.html file
  3. Deploy your site
  4. Done. Real-time traffic data should now be being tracked.
7

Gather User Feedback

  1. Create an account at UserJot
  2. Create a new Workspace for the app
  3. Done. Go to ‘My Board’ to see your public feedback/roadmap board.

Future Improvements (Coming soon…)

  • Creating Waitlists with Clerk
  • Feature flag integration + Recommended usage
  • Integrate Zustand for state management client-side
  • Implement stronger security rules with ArcJet (Bot detection, Rate limiting, Data Redaction, Email Validation, Application-level DDoS protection, etc.)
  • Create a Biome security linting plugin for automatically finding and fixing security issues + integrate into Stack
  • Add option for Kinde integration (for those who have more complex RBAC needs)