<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sean brydon</title>
    <description>The latest articles on DEV Community by sean brydon (@sean_brydon_5fb0311e13397).</description>
    <link>https://dev.to/sean_brydon_5fb0311e13397</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3898036%2Fc19fb034-bd80-4d28-8e8d-890f7e257a48.png</url>
      <title>DEV Community: sean brydon</title>
      <link>https://dev.to/sean_brydon_5fb0311e13397</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sean_brydon_5fb0311e13397"/>
    <language>en</language>
    <item>
      <title>I open-sourced my SaaS starter — here's the part I didn't</title>
      <dc:creator>sean brydon</dc:creator>
      <pubDate>Sat, 25 Apr 2026 21:22:32 +0000</pubDate>
      <link>https://dev.to/sean_brydon_5fb0311e13397/i-open-sourced-my-saas-starter-heres-the-part-i-didnt-4o65</link>
      <guid>https://dev.to/sean_brydon_5fb0311e13397/i-open-sourced-my-saas-starter-heres-the-part-i-didnt-4o65</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoof95cdto757q4kpirt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoof95cdto757q4kpirt.png" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've started the same SaaS project maybe a dozen times. Workspaces. Members. Roles. Billing webhooks. The "did this email actually verify or did Stripe fire the wrong event?" debugging session at 1am. Every time, the first two weeks of work were the same two weeks of work.&lt;/p&gt;

&lt;p&gt;So I built a starter kit. It's called Orbit, and the CLI to scaffold it is create-orb. Last month I open-sourced the core of it. This post is about what's free, what isn't, and why I drew the line where I did — because "freemium open source" is a phrase that gets a lot of side-eye, deservedly, and I want to be straight about how this one works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you get for free&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm create orb@latest my-app&lt;/code&gt;&lt;br&gt;
That command gives you, with no account and no payment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Hono API with proper DDD layering — bounded contexts, repositories, a UnitOfWork, an EventBus. Not because DDD is trendy, but because it's the structure I keep arriving at when a SaaS gets past the toy stage.&lt;/li&gt;
&lt;li&gt;Multi-tenant workspaces as the root primitive, with members and a workspace-scoped PBAC system. Two-scope permissions baked in (workspace + team), with requirePermission() middleware on the server and useCan() on the client.&lt;/li&gt;
&lt;li&gt;Auth via better-auth (magic links, OAuth, password + email verification).&lt;/li&gt;
&lt;li&gt;A choice between TanStack Start or Next.js App Router for the frontend. The CLI deletes the one you didn't pick. They share the UI library and the WebSocket client; the per-page code is intentionally duplicated so each variant stays idiomatic to its framework instead of being smeared across somelowest-common-denominator abstraction.&lt;/li&gt;
&lt;li&gt;Postgres via Prisma. Realtime over WebSockets. An in-memory rate limiter for dev. A 55-component internal UI library on Base UI + Tailwind v4 (coss.com).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rws2ja6uj0tj5d7g63z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rws2ja6uj0tj5d7g63z.png" alt=" " width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And a beautiful login page + onboarding tailored to creating your workspace&lt;/p&gt;

&lt;p&gt;That's the public starter. It's a real SaaS skeleton — you can ship something on it. Source is on GitHub, MIT, the lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's behind the paywall&lt;/strong&gt;&lt;br&gt;
Here's where I want to be direct, because this is the part people usually fudge.&lt;/p&gt;

&lt;p&gt;These features are not in the free starter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams — nested inside workspaces, with their own roles and permissions&lt;/li&gt;
&lt;li&gt;Billing — Stripe, Polar, and Dodo adapters behind a BillingProvider port&lt;/li&gt;
&lt;li&gt;Audit logs — both global (admin) and tenant-scoped ledgers, materialized by a post-commit projector&lt;/li&gt;
&lt;li&gt;Uploads — UploadThing adapter behind a FileStorage port&lt;/li&gt;
&lt;li&gt;Transactional email — Resend adapter behind a Mailer port&lt;/li&gt;
&lt;li&gt;Background jobs — Graphile Worker or QStash, swappable&lt;/li&gt;
&lt;li&gt;Remote rate limiting — Upstash or Unkey adapters &lt;/li&gt;
&lt;li&gt;Drizzle as an alternative to Prisma (same repository interfaces, same UoW)&lt;/li&gt;
&lt;li&gt;Waitlist mode for closed beta launches&lt;/li&gt;
&lt;li&gt;Many tailor skills specific to my DDD design choices. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  You can find the whole feature set and docs over at wereorbit.com
&lt;/h2&gt;

&lt;p&gt;I work at Cal.com as my day job - feel free to book me for anything tech related i.cal.com/sean&lt;/p&gt;

</description>
      <category>saas</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
