Skene
BLOG

ixartz SaaS-Boilerplate Review: PLG Audit 2026

Is the ixartz SaaS-Boilerplate good for product-led growth? We audited signup flow, feature gating, analytics, and billing. Score: 3/10 for PLG. The free version lacks checkout, trials, and analytics — those are PRO features.

·bySkene·LinkedIn
Summarize this article with LLMs

The ixartz SaaS-Boilerplate is one of the most starred open-source SaaS starters on GitHub with over 6,800 stars. It's built with Next.js, Clerk, Drizzle ORM, and Tailwind CSS — a modern stack for building multi-tenant SaaS applications.

We ran it through a comprehensive PLG skills audit — analyzing signup flow CRO, feature gating, trial optimization, product analytics, self-serve motion, and paywall design.

Overall PLG score: 3/10 — Excellent foundation for auth and multi-tenancy, but PLG features like checkout, trials, and analytics are explicitly marked as "PRO" features.


The full audit

CategoryScoreKey finding
Signup flow7/10Clerk integration with OAuth, magic link, multi-locale
Feature gating3/10Role-based access exists, but no plan-based gating
Trial optimization0/10No trial period tracking or logic
Product analytics2/10Sentry for errors only — no product analytics
Self-serve motion4/10Pricing UI exists, but checkout is PRO-only
Paywall/upgrade CRO2/10Static pricing page, no in-app upgrade prompts

1. Signup flow analysis

What's implemented

The signup delegates entirely to Clerk's hosted components:

// src/app/[locale]/(auth)/(center)/sign-up/[[...sign-up]]/page.tsx
import { SignUp } from '@clerk/nextjs';

const SignUpPage = (props: { params: { locale: string } }) => (
  <SignUp path={getI18nPath('/sign-up', props.params.locale)} />
);

Authentication options:

  • Email + password via Clerk
  • OAuth providers (Google, GitHub configurable)
  • Magic link support
  • Multi-locale support (en, fr)

The middleware handles Clerk session validation:

// src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtectedRoute = createRouteMatcher([
  '/dashboard(.*)',
  '/:locale/dashboard(.*)',
]);

What's missing

No custom signup form. You're locked into Clerk's UI and can't customize fields or add progressive profiling.

No signup analytics. No tracking events for:

  • Signup page viewed
  • Signup started
  • Signup completed
  • Email verified

2. Feature gating audit

What's implemented

Role-based access control with organization roles:

// src/types/Auth.ts
export const ORG_ROLE = {
  ADMIN: 'org:admin',
  MEMBER: 'org:member',
} as const;

export const ORG_PERMISSION = {
  // Add Organization Permissions here
} as const;

A ProtectFallback component exists for locked features:

// src/features/auth/ProtectFallback.tsx
export const ProtectFallback = (props: { trigger: React.ReactNode }) => {
  return (
    <Tooltip>
      <TooltipTrigger asChild>{props.trigger}</TooltipTrigger>
      <TooltipContent>
        <p>{t('not_enough_permission')}</p>
      </TooltipContent>
    </Tooltip>
  );
};

What's missing

No plan-based gating. The ORG_PERMISSION object is empty — no actual permissions are implemented.

Missing components:

  • No hasFeature() or canAccess() utility functions
  • No subscription tier checks
  • No usage limit enforcement
  • No upgrade prompts when limits are reached

3. Trial optimization

What's implemented

The database schema includes Stripe subscription fields:

-- src/migrations/0000_init-db.sql
CREATE TABLE IF NOT EXISTS "organization" (
  "stripe_subscription_status" text,
  "stripe_subscription_current_period_end" bigint,
  ...
);

What's missing

Trials are completely absent:

  • No trial_period, trial_end, or trial_started_at fields
  • No trial status enums
  • No trial email sequences
  • No trial countdown UI
  • No trial-to-paid conversion logic

4. Product analytics

What's implemented

Sentry for error monitoring only:

// src/instrumentation.ts
import * as Sentry from '@sentry/nextjs';

export async function register() {
  Sentry.init({
    dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
    tracesSampleRate: 1,
  });
}

Logtail for structured logging:

// src/libs/Logger.ts
if (Env.LOGTAIL_SOURCE_TOKEN) {
  stream = pino.multistream([
    await logtail({ sourceToken: Env.LOGTAIL_SOURCE_TOKEN }),
  ]);
}

What's missing

No product analytics provider:

  • No PostHog, Mixpanel, Amplitude, Segment, or GA4
  • No .track() or .capture() calls
  • No user identification
  • No feature usage tracking
  • No funnel analytics

Impact: You cannot measure signup-to-paid conversion, time-to-first-payment, or feature adoption.


5. Self-serve motion

What's implemented

Pricing configuration with three tiers:

// src/utils/AppConfig.ts
export const PricingPlanList: Record<string, PricingPlan> = {
  [PLAN_ID.FREE]: {
    price: 0,
    features: { teamMember: 2, website: 2, storage: 2, transfer: 2 },
  },
  [PLAN_ID.PREMIUM]: {
    price: 79,
    devPriceId: 'price_1PNksvKOp3DEwzQlGOXO7YBK',
    features: { teamMember: 5, website: 5, storage: 5, transfer: 5 },
  },
  [PLAN_ID.ENTERPRISE]: {
    price: 199,
    features: { teamMember: -1, website: -1, storage: -1, transfer: -1 },
  },
};

Pricing UI components exist for displaying plans.

What's missing

Checkout is explicitly a PRO feature:

// src/types/Subscription.ts comment
// PricingPlan is currently only used for Pricing section of the landing page.
// If you need a real Stripe subscription payment with checkout page,
// customer portal, webhook, etc. You can check out the Next.js Boilerplate Pro

Missing self-serve components:

  • No Stripe checkout session creation
  • No payment processing endpoint
  • No customer portal integration
  • No webhook handlers
  • No upgrade/downgrade flow

6. Paywall and upgrade CRO

What's implemented

Static pricing page with feature comparison:

// src/templates/Pricing.tsx
<PricingInformation
  buttonList={{
    [PLAN_ID.FREE]: (
      <Link href="/sign-up">{t('button_text')}</Link>
    ),
    [PLAN_ID.PREMIUM]: (
      <Link href="/sign-up">{t('button_text')}</Link>
    ),
  }}
/>

Note: All pricing buttons just link to signup — no checkout flow.

What's missing

No in-app upgrade prompts:

  • No "upgrade now" buttons in dashboard
  • No usage limit displays
  • No locked feature prompts with upgrade CTAs
  • No billing page (commented as PRO feature)

Database schema

The schema is well-structured for multi-tenancy:

TablePurpose
organizationMulti-tenant workspaces with Stripe fields
organization_membershipUser-to-org relationships with roles

Missing tables for PLG:

  • No usage_metrics or feature_usage
  • No trial_status tracking
  • No subscription_events audit log

What you need to add

Priority 1: Checkout flow (critical)

You'll need to implement Stripe checkout yourself or upgrade to the PRO version:

// Example implementation needed
export async function createCheckoutSession(priceId: string) {
  const session = await stripe.checkout.sessions.create({
    mode: 'subscription',
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: '/dashboard',
    cancel_url: '/pricing',
  });
  return session;
}

Priority 2: Analytics

Add PostHog or Mixpanel. Track at minimum:

track('signup_completed')
track('pricing_page_viewed')
track('checkout_started', { plan: 'premium' })
track('checkout_completed', { plan: 'premium' })

Priority 3: Feature gating

Implement the empty ORG_PERMISSION object with actual plan-based checks:

function canAccess(user, feature) {
  const plan = user.organization?.subscription_plan;
  return PLAN_FEATURES[plan]?.includes(feature);
}

First steps to PLG

ixartz gives you great multi-tenancy — here's how to add PLG on top:

Week 1: Decide build vs buy

The free version has no checkout. Your options:

  1. Buy PRO version — includes Stripe checkout, portal, webhooks
  2. Build yourself — add Stripe from scratch (2-3 days work)
  3. Use Paddle/Lemon Squeezy — simpler alternative to Stripe

If building yourself, start with a single "Pro" plan before adding tiers.

Week 2: Add analytics

  1. Install PostHog: npm install posthog-js
  2. Add provider in your root layout
  3. Use Clerk's user ID for posthog.identify()
  4. Track: signup_completed, org_created, checkout_started, subscription_activated

Week 3: Populate the permissions

The ORG_PERMISSION object is empty. Fill it in:

export const ORG_PERMISSION = {
  VIEW_ANALYTICS: 'org:view_analytics',
  EXPORT_DATA: 'org:export_data',
  MANAGE_BILLING: 'org:manage_billing',
} as const;

// Map to plans
const PLAN_PERMISSIONS = {
  free: [ORG_PERMISSION.VIEW_ANALYTICS],
  pro: [ORG_PERMISSION.VIEW_ANALYTICS, ORG_PERMISSION.EXPORT_DATA],
  enterprise: Object.values(ORG_PERMISSION),
};

Week 4: Add upgrade prompts

When users hit permission checks:

{canAccess(user, 'export_data') ? (
  <ExportButton />
) : (
  <UpgradeCard feature="Data Export" plan="Pro" />
)}

Key metrics to track

  • Organizations created per week
  • Time from org creation to first paid subscription
  • Feature adoption by plan (which pro features get used?)
  • Upgrade conversion rate from upgrade prompts

When to use this template

Good fit:

  • You want a solid multi-tenant foundation with Clerk
  • You're okay building checkout and analytics yourself
  • You need i18n support out of the box

Not ideal:

  • You need PLG features immediately
  • You want to avoid building Stripe integration from scratch
  • You need product analytics without additional work

Conclusion

The ixartz SaaS-Boilerplate scores 3/10 for PLG readiness. It's an excellent foundation for multi-tenant SaaS with modern tooling (Next.js 14, Clerk, Drizzle), but the free version is explicitly designed as a starting point — not a complete PLG solution.

The core PLG features (checkout, customer portal, webhooks, dark mode) are reserved for the paid PRO version. If you're building a PLG SaaS, you'll either need to:

  1. Build the monetization layer yourself
  2. Purchase the PRO version
  3. Use a different boilerplate with these features included

Frequently asked questions

Is the ixartz SaaS-Boilerplate really free?

The base version is free and open-source under MIT license. However, Stripe checkout, customer portal, dark mode, and billing management are "PRO" features that require purchasing the paid version.

Does it include Stripe integration?

The database schema includes Stripe fields, and pricing UI exists, but actual payment processing is not implemented in the free version. The code comments explicitly say to "check out the Next.js Boilerplate Pro" for checkout and webhooks.

How does it compare to other SaaS starters?

It has the strongest multi-tenant and i18n foundation of the open-source options, but the weakest PLG features. BoxyHQ and Saasfly include working Stripe checkout in their free versions.

Should I use Clerk for authentication?

Clerk simplifies auth significantly but locks you into their hosted UI. If you need custom signup forms or analytics on the signup flow, you may want more flexibility.


This analysis was performed using PLG Skills, an open-source framework for product-led growth audits. Skills used: signup-flow-cro, feature-gating, trial-optimization, product-analytics, self-serve-motion, paywall-upgrade-cro.

Done with this article? Explore more ways to ship real PLG.