One entry point for all organizations
<OrganizationList /> displays every membership in one place, for apps where users pick an organization before they enter.
Choose an account
to continue to acme


One account, multiple organizations
Roles and permissions are scoped to each organization. The same user can have different access across different organizations.
Choose an account
to continue to acme


Let users create organizations
One click launches <CreateOrganization />, where users can create an organization with a name and logo, then invite their team.
Choose an account
to continue to acme


Invitations made easy
When a user signs up, pending organization invitations are surfaced inline. They can accept and join an existing organization immediately.
Choose an account
to continue to acme


Automate access requests
Users can request to join an organization. Matching email domains are suggested to the right organizations automatically, no manual invites needed.
Choose an account
to continue to acme


Allow personal account switching
If enabled, users can access their personal workspace and organizations. Ideal for hybrid B2B and B2C apps like GitHub.
Choose an account
to continue to acme


Customizable to your brand
Match the look and feel of your product with full styling control. Override themes, layout, and behaviors to create an account menu that feels native to your app.

Implement organization list in minutes
Drop-in <OrganizationList />
Build secure, scalable authentication in minutes with Clerk’s SDKs. Drop in pre-built UI components and onboard users instantly, without friction or security concerns.
Clerk API
Custom flows
Want full control over your onboarding experience? Our headless APIs give you the flexibility to build exactly what you need.
"use client"
import { useAuth, useOrganizationList } from "@clerk/nextjs"
import CreateOrganization from "../components/create-organization"
// List user's organization memberships
export default function OrganizationSwitcher() {
const { isLoaded, setActive, userMemberships } = useOrganizationList({
userMemberships: {
// Set pagination parameters
pageSize: 5,
keepPreviousData: true,
},
})
const { orgId } = useAuth()
if (!isLoaded) {
return <p>Loading...</p>
}
return (
<>
<h1>Joined organizations</h1>
{userMemberships?.data?.length > 0 && (
<>
<table>
<thead>
<tr>
<th>Identifier</th>
<th>Organization</th>
<th>Joined</th>
<th>Role</th>
<th>Set as active org</th>
</tr>
</thead>
<tbody>
{userMemberships?.data?.map((mem) => (
<tr key={mem.id}>
<td>{mem.publicUserData.identifier}</td>
<td>{mem.organization.name}</td>
<td>{mem.createdAt.toLocaleDateString()}</td>
<td>{mem.role}</td>
<td>
{orgId === mem.organization.id ? (
<button
onClick={() =>
setActive({ organization: mem.organization.id })
}
>
Set as active
</button>
) : (
<p>Currently active</p>
)}
</td>
</tr>
))}
</tbody>
</table>
<div>
<button
disabled={
!userMemberships?.hasPreviousPage || userMemberships?.isFetching
}
onClick={() => userMemberships?.fetchPrevious?.()}
>
Previous
</button>
<button
disabled={
!userMemberships?.hasNextPage || userMemberships?.isFetching
}
onClick={() => userMemberships?.fetchNext?.()}
>
Next
</button>
</div>
</>
)}
{userMemberships?.data?.length === 0 && (
<div>
<p>No organizations found</p>
<CreateOrganization />
</div>
)}
</>
)
}
