Skip to main content

Best Boilerplates With Polar.sh Payments 2026

·StarterPick Team
Share:

Polar.sh is the payments infrastructure platform gaining traction in the developer-tools and indie hacker space. It charges 4% + $0.40 per transaction — higher than Stripe's 2.9% + $0.30 — but includes something Stripe doesn't: automatic tax collection and remittance in 40+ countries. Polar acts as the Merchant of Record, meaning you receive net payouts and never deal with VAT, GST, or sales tax compliance.

For solo developers and small teams shipping software products, that tax compliance feature is worth more than the fee difference. The best SaaS boilerplates have recognized this and ship with Polar.sh as an option (or primary) billing provider.

Polar.sh vs Stripe: The Real Comparison

FeaturePolar.shStripe
Transaction fee4% + $0.402.9% + $0.30
Merchant of Record✅ You're not the seller❌ You're the seller
Tax collection✅ Automatic (40+ countries)❌ Stripe Tax add-on (+0.5%)
VAT/GST compliance✅ Handled❌ You handle it
License key delivery✅ Automatic❌ Custom code
GitHub sponsor tiers
Subscription webhooks
Usage-based billing
Free tier4% from first sale$0 fees (just 2.9%)
Open source✅ Core is open source
One-time products

When Polar wins over Stripe:

  • You're selling to global customers (VAT compliance worth the extra 1.1%)
  • You're an indie hacker selling to developers who expect Polar checkout
  • You ship digital goods that Polar auto-delivers (license keys, file downloads)
  • Tax compliance overhead would require hiring an accountant

When Stripe wins over Polar:

  • You're US-only with low-volume (simpler tax situation)
  • You need Stripe-specific features (Stripe Connect for marketplace, Advanced Fraud Tools)
  • Your target market is enterprise (Stripe's brand recognition)

Quick Comparison

BoilerplatePricePrimary BillingAuthStack
Open SaaSFreeStripe + Polar.shWasp AuthWasp + React + Node
RSKFreePolar.shClerkReact Router v7 + Convex
Supastarter$149Stripe + Polar.shBetter AuthNext.js + Drizzle
v1.runFreePolar.shBetter AuthNext.js + Convex
xaas-cloud/polar-paymentFreePolar.shN/ANext.js

1. Open SaaS — Best Free Polar.sh Boilerplate

Price: Free (MIT) | Creator: Wasp | Stack: Wasp + React + Node.js + Prisma

Open SaaS is a 100% free SaaS boilerplate that ships with both Stripe and Polar.sh billing out of the box — you choose which to use (or use both). It's the most complete free boilerplate that includes Polar.sh, and it comes with:

  • Email/password + social auth (Google, GitHub)
  • Stripe subscriptions (webhook handling included)
  • Polar.sh subscriptions as alternative
  • Background jobs via Wasp actions
  • Email sending via SendGrid or Resend
  • Admin dashboard
  • Landing page with pricing section
  • Analytics via Plausible or Google Analytics

Polar.sh integration in Open SaaS:

// src/payment/paymentProcessor.ts
import { PolarPaymentProcessor } from './polar';
import { StripePaymentProcessor } from './stripe';

// Switch between providers by changing this:
export const paymentProcessor: PaymentProcessor =
  process.env.PAYMENTS_PROVIDER === 'polar'
    ? new PolarPaymentProcessor()
    : new StripePaymentProcessor();
// Polar.sh webhook handler
// src/payment/polar.ts
import { Webhooks } from '@polar-sh/sdk/webhooks';

export async function handlePolarWebhook(req: Request) {
  const webhooks = new Webhooks({
    webhookSecret: process.env.POLAR_WEBHOOK_SECRET!,
  });

  const event = await webhooks.constructEvent(
    await req.text(),
    req.headers.get('polar-signature')!
  );

  switch (event.type) {
    case 'subscription.created':
    case 'subscription.updated':
      await updateUserSubscription({
        polarCustomerId: event.data.customer_id,
        status: event.data.status,
        productId: event.data.product_id,
      });
      break;

    case 'subscription.canceled':
      await cancelUserSubscription({
        polarCustomerId: event.data.customer_id,
      });
      break;
  }
}

2. v1.run — Best Modern Stack with Polar.sh

Price: Free (MIT) | Stack: Next.js 15 + Convex + Better Auth + Polar.sh

v1.run uses Polar.sh as its only billing provider — not as an add-on alongside Stripe. This makes it the most Polar.sh-native free starter: the entire billing experience is built for Polar's SDK and webhook patterns.

Polar.sh checkout with the SDK:

// app/api/checkout/route.ts
import { Polar } from '@polar-sh/sdk';

const polar = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN!,
  server: 'production',
});

export async function POST(req: Request) {
  const { priceId, userId } = await req.json();

  const checkout = await polar.checkouts.create({
    products: [{ productPriceId: priceId }],
    customerId: userId, // Link to your user ID
    successUrl: `${process.env.NEXT_PUBLIC_URL}/dashboard?checkout=success`,
    metadata: {
      userId, // Available in webhook payload
    },
  });

  return Response.json({ url: checkout.url });
}

3. RSK (React Starter Kit) — Best React Router v7 + Polar

Price: Free (MIT) | Stack: React Router v7 + Convex + Clerk + Polar.sh

RSK pairs React Router v7 with Polar.sh specifically because both are developer-community-oriented tools. The combination (React Router + Convex + Clerk + Polar) is modern, well-documented, and free to use.

RSK's Polar subscription management:

// app/routes/billing.tsx
import type { Route } from './+types/billing';
import { Polar } from '@polar-sh/sdk';

export async function loader({ request }: Route.LoaderArgs) {
  const user = await getUser(request);

  const polar = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN! });

  // Get customer's subscriptions
  const subscriptions = await polar.subscriptions.list({
    customerId: user.polarCustomerId ?? undefined,
  });

  // Get available products
  const products = await polar.products.list({
    organizationId: process.env.POLAR_ORGANIZATION_ID!,
    isArchived: false,
  });

  return { subscriptions: subscriptions.result.items, products: products.result.items };
}

4. Supastarter (Polar Edition) — Best Commercial Option

Price: $149 | Stack: Next.js + Better Auth + Drizzle + Polar.sh (optional Stripe)

Supastarter ships with both Stripe and Polar.sh integration — switch between them via environment variable. The Polar integration includes subscription creation, webhook handling, subscription portal (users manage their own subscriptions), and plan upgrade/downgrade flows.

Switching providers in Supastarter:

# .env
PAYMENTS_PROVIDER=polar  # or "stripe"
POLAR_ACCESS_TOKEN=...
POLAR_ORGANIZATION_ID=...
POLAR_WEBHOOK_SECRET=...

# Supastarter detects PAYMENTS_PROVIDER at startup
# and loads the appropriate billing adapter

Setting Up Polar.sh From Scratch

For any boilerplate you're adding Polar to:

# Install the Polar SDK
bun add @polar-sh/sdk
# or
npm install @polar-sh/sdk
// lib/polar.ts — Polar client setup
import { Polar } from '@polar-sh/sdk';

export const polar = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN!,
  server: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
});
// Create a checkout session
export async function createPolarCheckout(
  productPriceId: string,
  userId: string,
  email: string
) {
  return await polar.checkouts.create({
    products: [{ productPriceId }],
    customerEmail: email,
    metadata: { userId },
    successUrl: `${process.env.APP_URL}/dashboard?checkout=success`,
    embedOrigin: process.env.APP_URL, // For embedded checkout
  });
}
// Webhook handling (Next.js App Router)
// app/api/webhooks/polar/route.ts
import { validateEvent } from '@polar-sh/sdk/webhooks';

export async function POST(req: Request) {
  const body = await req.text();
  const signature = req.headers.get('polar-signature') ?? '';

  let event;
  try {
    event = validateEvent(body, req.headers, process.env.POLAR_WEBHOOK_SECRET!);
  } catch {
    return Response.json({ error: 'Invalid signature' }, { status: 403 });
  }

  // Handle subscription events
  if (event.type === 'subscription.created') {
    await prisma.user.update({
      where: { polarCustomerId: event.data.customer_id },
      data: {
        subscriptionStatus: 'active',
        polarSubscriptionId: event.data.id,
        polarProductId: event.data.product_id,
      },
    });
  }

  return Response.json({ received: true });
}

Polar.sh Products to Sell From Your SaaS

Polar isn't just subscriptions — it handles multiple product types:

// Types of Polar products:

// 1. Subscriptions (monthly/annual)
await polar.products.create({
  name: 'Pro Plan',
  description: '...',
  prices: [
    { type: 'recurring', amount: 900, currency: 'usd', recurringInterval: 'month' },
    { type: 'recurring', amount: 7200, currency: 'usd', recurringInterval: 'year' },
  ],
});

// 2. One-time purchases (templates, licenses, ebooks)
await polar.products.create({
  name: 'Lifetime Access',
  prices: [{ type: 'one_time', amount: 29900, currency: 'usd' }],
  benefits: [
    { type: 'license_keys' }, // Auto-delivers license key on purchase
  ],
});

// 3. Free (with benefits for GitHub sponsors)
await polar.products.create({
  name: 'GitHub Sponsors',
  prices: [{ type: 'free' }],
  benefits: [{ type: 'github_repository' }], // Grant repo access
});

Find all Polar.sh compatible boilerplates at StarterPick.

Related: Best Convex Boilerplates for SaaS 2026 · Best Boilerplates Using Better Auth 2026

Review OpenSaaS and compare alternatives on StarterPick.

Polar.sh Benefit System: Beyond Subscriptions

Polar's most distinctive feature compared to Stripe is its benefit system — the ability to automatically deliver value when a customer purchases a product. This changes the developer experience for certain product categories.

When a customer subscribes to a Polar product with a license_keys benefit, Polar automatically generates and delivers a license key to the customer's email at checkout. Your webhook handler receives the subscription.created or order.created event with the license key ID included in the payload. You don't write license key generation logic — Polar handles generation, delivery, and revocation. For traditional software licenses (desktop apps, CLI tools, VS Code extensions), this eliminates a common 4–8 hour implementation task.

The GitHub repository access benefit is specific to developer tools. When a customer subscribes to a product with github_repository benefits, Polar automatically invites the customer's GitHub account to a private repository you specify. When the subscription lapses or is cancelled, Polar removes the access. For private repositories containing course materials, premium templates, or access-controlled codebases, this is the entire access management system — no custom webhook handler needed.

The Discord server access benefit works similarly. Customers who subscribe to a product with discord_server benefits receive automatic Discord server role assignment and removal. For developer communities where premium Discord access is part of the value proposition (exclusive channels, direct access to the creator), Polar's benefit system replaces a custom Discord bot and webhook integration.

The practical implication for boilerplate selection: if your product model combines subscriptions with automatic benefit delivery (license keys, private repo access, Discord roles), the Open SaaS + Polar.sh combination is particularly well-suited. Open SaaS provides the SaaS foundation; Polar handles the product delivery layer that would require custom development against Stripe.

Migrating from Stripe to Polar.sh: The Real Effort

For boilerplates already running on Stripe, migrating to Polar.sh involves more than swapping webhook handlers. The data model differences require careful migration planning.

The core difference: Stripe stores customers as Customer objects with a unique customer ID. Polar stores customers in their system with a separate Polar customer ID. If your boilerplate stores stripeCustomerId on your User record and uses it for checkout creation, subscription lookup, and portal sessions, you need to either add a polarCustomerId column alongside the Stripe column (for incremental migration) or replace the entire billing integration at once.

The incremental migration approach is safer for products with existing paying customers. Add Polar as a parallel billing option for new sign-ups. Existing customers on Stripe subscriptions remain on Stripe until their subscription naturally renews. At renewal, offer them a migration to the new Polar billing with a transition incentive. This avoids forcing paying customers through a billing transition and reduces churn risk.

The webhook handler migration is the most mechanical part. Polar's events (subscription.created, subscription.updated, subscription.canceled, order.created) map directly to Stripe's equivalent events. The handler logic is nearly identical — receive event, validate signature, update user record in your database. The main difference: subscription status values differ between providers (Stripe uses active, past_due, canceled; Polar uses its own status vocabulary). Map these carefully in your handler to avoid users being unexpectedly downgraded.

Customer portal functionality (letting users manage their own subscription) is fully supported by Polar. The Polar customer portal URL is generated similarly to Stripe's billing portal session — call polar.customerPortals.create({ customerId }) and redirect the user. The portal allows them to cancel, upgrade, and update payment methods without any additional frontend work on your part.

Understanding Polar.sh's Open Source Model

Polar.sh positions itself as the payments platform built by developers for developers, and its open source core is a genuine differentiator for certain types of buyers.

Polar's core platform is open source (MIT licensed), which means you can see exactly how your transactions are processed, how webhooks are generated, and how the customer data model is structured. For buyers who care about vendor lock-in or regulatory transparency requirements, the ability to audit the platform code is a meaningful trust signal.

The open source model also means Polar can be self-hosted. While most developers use Polar's managed cloud service, the option to self-host creates a useful exit ramp. A product that outgrows Polar's managed service (or has data residency requirements that conflict with using a US-hosted service) can migrate to a self-hosted Polar instance without changing any integration code. The API contract is the same.

For developer tools and open source projects specifically, Polar's alignment with developer community values affects customer perception beyond just the technical integration. Developer buyers are aware of Polar's open source positioning, GitHub integration, and creator-first philosophy. For a CLI tool or VS Code extension, using Polar as your payment provider signals a certain product philosophy that resonates with developer buyers in a way that a Stripe-powered checkout page does not. This is a soft factor, but it influences conversion rates in developer-focused markets.


Compare Polar.sh against Stripe and LemonSqueezy in full detail: Stripe vs LemonSqueezy for SaaS 2026.

See which boilerplates include payment processing pre-configured in the best SaaS boilerplates guide.

Check out this boilerplate

View Open SaaSon StarterPick →

The SaaS Boilerplate Matrix (Free PDF)

20+ SaaS starters compared: pricing, tech stack, auth, payments, and what you actually ship with. Updated monthly. Used by 150+ founders.

Join 150+ SaaS founders. Unsubscribe in one click.