PLG Readiness Audit: CMSaasStarter — 3.7/10
We audited this repo for product-led growth readiness using the open-source PLG Skills framework. Here's what we found across 6 categories.
Overall: 3.7/10 — Best Stripe integration of any SvelteKit starter — full checkout, automatic customer creation, billing portal, and webhooks that actually update state. But no analytics and no feature gating.
| Category |
Score |
Finding |
| Signup flow |
7/10 |
Supabase Auth UI with GitHub OAuth |
| Feature gating |
2/10 |
Static pricing table, no runtime checks |
| Trial optimization |
1/10 |
Stripe trialing status recognized, not implemented |
| Product analytics |
0/10 |
Documentation explains how to add PostHog, nothing installed |
| Self-serve motion |
9/10 |
Full Stripe checkout + billing portal + customer creation |
| Paywall/upgrade CRO |
3/10 |
Pricing page with plan indicator, no in-app prompts |
Self-serve billing: best of any SvelteKit starter (9/10)
Full Stripe checkout with automatic customer creation on first purchase:
// src/routes/(admin)/account/subscribe/[slug]/+page.server.ts
const stripeSession = await stripe.checkout.sessions.create({
line_items: [{ price: params.slug, quantity: 1 }],
customer: customerId,
mode: "subscription",
success_url: `${url.origin}/account`,
cancel_url: `${url.origin}/account/billing`,
});
Billing portal gives users full self-serve management (upgrade, downgrade, cancel, update payment, view invoices). The pricing module shows a "Current Plan" badge for the active subscription:
<!-- src/routes/(marketing)/pricing/pricing_module.svelte -->
{#if plan.id === currentPlanId}
<Badge>Current Plan</Badge>
{:else}
<Button>{callToAction}</Button>
{/if}
Compared to JustShip (the other SvelteKit starter we reviewed), the webhooks here actually work — they update user state, not just log to console.
Feature gating: limits shown but never checked
The pricing table defines feature limits:
{ name: "Feature 3", freeString: "3", proString: "Unlimited" }
But nowhere in the code are these limits enforced. No hasFeature(), no route gating by plan, no usage counting, no locked UI components. All features are available to everyone regardless of plan.
Analytics: docs exist, code doesn't
There's an analytics_docs.md file explaining how to add PostHog or GA4. But no analytics package is in package.json and no tracking calls exist in the codebase. You can't measure signup-to-paid conversion without adding analytics yourself.
Trials: status-aware, not implemented
The subscription handling recognizes trialing as a valid active status:
const primaryStripeSubscription = stripeSubscriptions.data.find((x) => {
return x.status === "active" || x.status === "trialing" || x.status === "past_due";
});
But no trial period is passed to Stripe checkout, no trial countdown exists, and no trial emails are sent.
What you'd need to add
1. Install PostHog. The docs already explain how — just do it:
<!-- src/routes/+layout.svelte -->
<script>
import posthog from 'posthog-js';
import { browser } from '$app/environment';
if (browser) {
posthog.init('your_key', { api_host: 'https://app.posthog.com' });
}
</script>
Track: signup_completed, pricing_page_viewed, checkout_started, subscription_activated, feature_used.
2. Add subscription checking. Create a helper:
export async function getSubscription(customerId: string) {
const subscriptions = await stripe.subscriptions.list({
customer: customerId, status: 'active',
});
return subscriptions.data[0];
}
export function getPlanFromPriceId(priceId: string) {
const plans = { 'price_free': 'free', 'price_xxx': 'pro' };
return plans[priceId] || 'free';
}
3. Gate one feature. Pick one feature to put behind Pro:
{#if isPro}
<ProFeature />
{:else}
<UpgradePrompt feature="advanced_export" />
{/if}
4. Add trial to checkout. One parameter:
const stripeSession = await stripe.checkout.sessions.create({
// ... existing config
subscription_data: { trial_period_days: 14 },
});
Full analysis with database schema review: CMSaasStarter PLG Audit
Audit methodology: PLG Skills (open source). You can also run uvx skene-growth analyze . (skene-growth) to scan any codebase for PLG gaps.
PLG Readiness Audit: CMSaasStarter — 3.7/10
We audited this repo for product-led growth readiness using the open-source PLG Skills framework. Here's what we found across 6 categories.
Overall: 3.7/10 — Best Stripe integration of any SvelteKit starter — full checkout, automatic customer creation, billing portal, and webhooks that actually update state. But no analytics and no feature gating.
trialingstatus recognized, not implementedSelf-serve billing: best of any SvelteKit starter (9/10)
Full Stripe checkout with automatic customer creation on first purchase:
Billing portal gives users full self-serve management (upgrade, downgrade, cancel, update payment, view invoices). The pricing module shows a "Current Plan" badge for the active subscription:
Compared to JustShip (the other SvelteKit starter we reviewed), the webhooks here actually work — they update user state, not just log to console.
Feature gating: limits shown but never checked
The pricing table defines feature limits:
But nowhere in the code are these limits enforced. No
hasFeature(), no route gating by plan, no usage counting, no locked UI components. All features are available to everyone regardless of plan.Analytics: docs exist, code doesn't
There's an
analytics_docs.mdfile explaining how to add PostHog or GA4. But no analytics package is inpackage.jsonand no tracking calls exist in the codebase. You can't measure signup-to-paid conversion without adding analytics yourself.Trials: status-aware, not implemented
The subscription handling recognizes
trialingas a valid active status:But no trial period is passed to Stripe checkout, no trial countdown exists, and no trial emails are sent.
What you'd need to add
1. Install PostHog. The docs already explain how — just do it:
Track:
signup_completed,pricing_page_viewed,checkout_started,subscription_activated,feature_used.2. Add subscription checking. Create a helper:
3. Gate one feature. Pick one feature to put behind Pro:
{#if isPro} <ProFeature /> {:else} <UpgradePrompt feature="advanced_export" /> {/if}4. Add trial to checkout. One parameter:
Full analysis with database schema review: CMSaasStarter PLG Audit
Audit methodology: PLG Skills (open source). You can also run
uvx skene-growth analyze .(skene-growth) to scan any codebase for PLG gaps.