GROWTH PATTERN

Adding Freemium Gating to SvelteKit + Supabase Apps

SvelteKit + Supabase with payments handles subscriptions, but free users can consume unlimited resources without hitting conversion triggers.

SvelteKit + Supabase

Last updated:

What's Missing in Standard SvelteKit + Supabase Architecture

While SvelteKit + Supabase handles billing correctly, it doesn't monitor feature usage or trigger upgrade prompts when free users hit limits. Payment processing works, but usage tracking is separate.

Standard SvelteKit + Supabase Flow vs Optimized Skene Flow

Standard Flow
1

User subscribes via payments

2

Subscription status stored in Supabase

3

Features accessible but no usage limits enforced

Skene Flow
1

Track usage in Supabase 'subscriptions' and 'usage' tables

2

Detect when free tier user hits limit (e.g., 10 projects created)

3

Block feature access and trigger upgrade prompt email

4

Track conversion from free to paid

Visual comparison of the flows:

Loading diagram...

How Skene Fixes This

The Skene infrastructure for SvelteKit + Supabase tracks usage in Supabase and integrates with payments to enforce subscription limits. It automatically gates features and sends conversion-focused email sequences when free tier limits are reached.

Implementation Comparison

Using Skene Infrastructure

Install via Prompt

cursor.mdc
@task: Initialize Skene.
@action: Analyze my local code, validating subscription via `npx skene login`, and generate `skene.config.ts` to implement the Freemium Gating pattern for SvelteKit + Supabase.

Copy Skene Prompt for Cursor

Generated skene.config.ts

skene.config.ts
// skene.config.ts - The Automated Way
import { defineLoop } from '@skene/sdk';

export default defineLoop({
  type: 'freemium',
  opinion: 'Enforce usage limits for free tier users and trigger upgrade prompts',
  steps: [
    {
      trigger: {
        type: 'api',
        endpoint: '/api/features/*',
        method: 'POST'
      },
      condition: {
        type: 'usage',
        limit: {
          free: 100,
          paid: Infinity
        },
        period: '30d'
      },
      action: {
        type: 'block',
        message: 'You've reached your free tier limit. Upgrade to continue.',
        upgradePrompt: {
          type: 'email',
          provider: 'resend',
          template: 'upgrade_prompt'
        }
      }
    }
  ],
  recovery: {
    retries: 0 // No retries for blocking actions
  }
});

Frequently asked questions