Hype StackHypeStack

Organizations

Organizations are the multi-tenant boundary in both SaaS starters. Users belong to organizations, invitations bring new members in, and API routes scope work to the active organizationId on the request context.

Credential-free setup notes live on the starter pack pages. This page is the domain model and code paths.

What ships with a starter

ConceptRole
OrganizationTenant boundary for data and settings
Membership + roleTies a user to an org with a permission preset (admin, member, ...)
InvitationEmail invite into an organization
Permissions (CASL)Server-side hasAccess checks mirrored in the UI
OnboardingFirst-time flow to create or join an org before the private app

Where the code lives

PiecePath pattern
Organization featuresapps/backend/src/features/organizations/modules/
Organization routesapps/backend/src/routes/organizations/
Invitation socketsapps/backend/src/sockets/invitations/
Permission presets / subjectspackages/enums (or the enums package your stack installs)
hasAccess middlewareapps/backend/src/middleware/permissions/has-access.ts
Frontend org settingsapps/frontend/src/features/settings/modules/organization-tab/
Onboarding routesapps/frontend/src/routes/onboarding/

WorkOS vs Better Auth membership storage

WorkOS starterBetter Auth starter
MembershipsWorkOS organization memberships APILocal Prisma Member + Organization models
InvitationsLocal OrganizationInvitation plus emailSame invitation feature modules; Better Auth's own Invitation model is unused by the app flow
Org settings / logosLocal Prisma + storage uploadsSame

Both starters expose the same product UX: create org, invite members, manage roles, enforce hasAccess on routes.

Permission flow

From session to route gate

  1. withAuthUser

    Resolves the signed-in user and active organization membership.

  2. resolvePermissionsForMembership

    Loads the role permissions for that membership (WorkOS API or Prisma, depending on starter).

  3. buildAbilityFromPermissions

    Turns the permission list into a CASL ability on the Hono context.

  4. hasAccess({ action, subject })

    Route middleware denies the request when ability.can fails.

When you add a new domain (for example teams or projects), register subjects and grant them on the right roles. The teams pack notes that you may need to add CASL subjects manually after install.

Invitations

Organization invitation modules handle send, accept, and resend. Accepting an invite attaches the user to the org and continues into the private app. Email delivery needs Resend configured; see Mailing.

Teams pack relationship

pack-teams adds teams inside an organization (Team, TeamMember, team invitations). It does not replace org membership. Org role still gates who can manage teams; team membership is a second layer for collaboration inside one tenant.

pack-projects is the same idea for projects and project members.

Practical guidance

  • Scope queries by organizationId from context. Do not trust a client-supplied org id without membership checks.
  • Keep new permission subjects in the shared enums package so frontend and backend stay aligned.
  • For admin-wide views across all orgs, use the admin app, not the customer frontend.
Sponsor open source

Every purchase and sponsorship funds my 8+ years of work on open source given freely to the community. It keeps the lights on, funds new packs, and keeps the ecosystem alive. Even a small tier means a lot. Thank you!

Sponsor on GitHub