Skip to main content

Indie Kit Review 2026: SvelteKit for Solo Developers

·StarterPick Team
indie-kitsveltekitreviewboilerplate2026

TL;DR

Indie Kit is a lean SvelteKit SaaS starter designed for solo developers who want to ship quickly without unnecessary complexity. Smaller feature set than SvelteShip, lower price (~$79-$99), and a refreshingly minimal codebase. Best for indie hackers who want to read and understand every line before customizing.

What You Get

Price: ~$79-$99 (check the creator's site for current pricing)

Core features:

  • SvelteKit + TypeScript
  • Auth: Lucia Auth
  • Payments: Stripe (one-time or subscriptions)
  • Email: Resend
  • Database: Prisma + PostgreSQL
  • UI: Tailwind (minimal components)
  • SEO basics

The Minimalist Philosophy

Indie Kit's value proposition is simplicity. The codebase is intentionally small:

indie-kit/
├── src/
│   ├── routes/
│   │   ├── (auth)/
│   │   │   ├── login/
│   │   │   └── signup/
│   │   ├── (app)/
│   │   │   └── dashboard/
│   │   └── api/
│   │       ├── webhooks/
│   │       └── checkout/
│   ├── lib/
│   │   ├── auth.ts          ← 80 lines
│   │   ├── stripe.ts        ← 60 lines
│   │   └── email.ts         ← 40 lines
│   └── server/
└── prisma/schema.prisma

The auth module is 80 lines. The Stripe module is 60 lines. You can read the entire codebase in 30 minutes and understand exactly what it does.


Clean SvelteKit Patterns

// src/hooks.server.ts — auth in 25 lines
import { lucia } from '$lib/auth';
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
  const sessionId = event.cookies.get(lucia.sessionCookieName);

  if (!sessionId) {
    event.locals.user = null;
    event.locals.session = null;
    return resolve(event);
  }

  const { session, user } = await lucia.validateSession(sessionId);

  if (session?.fresh) {
    const cookie = lucia.createSessionCookie(session.id);
    event.cookies.set(cookie.name, cookie.value, { path: '.', ...cookie.attributes });
  }

  if (!session) {
    const blankCookie = lucia.createBlankSessionCookie();
    event.cookies.set(blankCookie.name, blankCookie.value, { path: '.', ...blankCookie.attributes });
  }

  event.locals.user = user;
  event.locals.session = session;
  return resolve(event);
};
<!-- src/routes/(app)/dashboard/+page.svelte -->
<script lang="ts">
  import type { PageData } from './$types';

  let { data } = $props<{ data: PageData }>();
</script>

<h1>Welcome back, {data.user.email}</h1>

{#if data.isPro}
  <ProFeatures />
{:else}
  <UpgradePrompt />
{/if}
// src/routes/(app)/dashboard/+page.server.ts
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ locals }) => {
  if (!locals.user) redirect(302, '/login');

  const subscription = await getActiveSubscription(locals.user.id);

  return {
    user: locals.user,
    isPro: subscription?.status === 'active',
  };
};

One-Time vs Subscription Payments

Indie Kit supports both models — useful for info products or lifetime licenses:

// src/routes/api/checkout/+server.ts
export const POST: RequestHandler = async ({ request, locals }) => {
  if (!locals.user) return json({ error: 'Unauthorized' }, { status: 401 });

  const { mode } = await request.json();

  const sessionConfig = mode === 'payment'
    ? {
        mode: 'payment' as const,
        line_items: [{ price: env.STRIPE_LIFETIME_PRICE_ID, quantity: 1 }],
      }
    : {
        mode: 'subscription' as const,
        line_items: [{ price: env.STRIPE_MONTHLY_PRICE_ID, quantity: 1 }],
        subscription_data: { trial_period_days: 14 },
      };

  const session = await stripe.checkout.sessions.create({
    customer: locals.user.stripeCustomerId,
    ...sessionConfig,
    success_url: `${BASE_URL}/dashboard?success=true`,
    cancel_url: `${BASE_URL}/pricing`,
  });

  return json({ url: session.url });
};

This flexibility is useful for indie products that sell both subscriptions and lifetime deals.


Limitations

  • No blog included (add Svelte content or write MDX yourself)
  • No admin panel
  • Minimal UI components (you build most UI yourself)
  • Small community (harder to find specific answers)
  • Less documentation than larger boilerplates

Indie Kit vs SvelteShip

FeatureIndie KitSvelteShip
Price~$79-99~$149
Blog
UI componentsMinimalSkeleton UI
Codebase sizeSmall (easy to read)Medium
Svelte 5 runesVaries
One-time + subscriptionSubscription only

Indie Kit for minimalism and lower cost; SvelteShip for more complete feature set.


Who Should Buy Indie Kit

Good fit:

  • Solo developers who want to read and own every line of code
  • Info product creators (courses, ebooks) needing one-time payment support
  • SvelteKit developers building their first SaaS
  • Budget-conscious founders

Bad fit:

  • Teams needing admin panel or blog out of the box
  • Products with complex UI requirements
  • Teams who need community support resources

Final Verdict

Rating: 3/5

Indie Kit delivers exactly what it promises: a minimal, readable SvelteKit foundation for solo developers. The low price and clean codebase are genuine strengths. The limited features mean more building on your own — appropriate for developers who see that as a feature, not a limitation.


Compare Indie Kit with other SvelteKit starters on StarterPick.

Check out this boilerplate

View Indie Kit on StarterPick →

Comments