Clerk Authentication
Jazz can be integrated with Clerk to authenticate users. This method combines Clerk's comprehensive authentication services with Jazz's local-first capabilities.
How it works
When using Clerk authentication:
- Users sign up or sign in through Clerk's authentication system
- Jazz securely stores the user's account keys with Clerk
- When logging in, Jazz retrieves these keys from Clerk
- Once authenticated, users can work offline with full Jazz functionality
This authentication method is not fully local-first, as login and signup need to be done online, but once authenticated, users can use all of Jazz's features without needing to be online.
Key benefits
- Rich auth options: Email/password, social logins, multi-factor authentication
- User management: Complete user administration dashboard
- Familiar sign-in: Standard auth flows users already know
- OAuth providers: Google, GitHub, and other popular providers
- Enterprise features: SSO, SAML, and other advanced options
Implementation
Use <JazzReactProviderWithClerk />
to wrap your app:
import {
const useClerk: () => LoadedClerk
useClerk,const ClerkProvider: React.ComponentType<ClerkProviderProps>
ClerkProvider } from '@clerk/clerk-react'; import {JazzReactProviderWithClerk } from "jazz-tools/react"; function
const JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => JSX.Element | null
JazzProvider({
function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Element
children: React.ReactNode
children }: {children: React.ReactNode
children: React.type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<...> | null | undefined
Represents all of the things React can render. Where {@link ReactElement } only represents JSX, `ReactNode` represents everything that can be rendered.ReactNode }) { constconst clerk: LoadedClerk
clerk =function useClerk(): LoadedClerk
useClerk(); return ( <JazzReactProviderWithClerk
const JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => JSX.Element | null
clerk: MinimalClerkClient
clerk={const clerk: LoadedClerk
clerk}sync: SyncConfig
sync={{peer: "wss://cloud.jazz.tools/?key=you@example.com"
peer: `wss://cloud.jazz.tools/?key=${const apiKey: "you@example.com"
apiKey}`, }} > {children: React.ReactNode
children} </JazzReactProviderWithClerk> ); }
const JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => JSX.Element | null
function createRoot(container: Container, options?: RootOptions): Root
createRoot lets you create a root to display React components inside a browser DOM node.createRoot(var document: Document
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/document)document.Document.getElementById(elementId: string): HTMLElement | null
Returns a reference to the first object with the specified value of the ID attribute.getElementById("root")!).Root.render(children: React.ReactNode): void
render( <const ClerkProvider: React.ComponentType<ClerkProviderProps>
ClerkProviderpublishableKey: string
The Clerk publishable key for your instancepublishableKey={const PUBLISHABLE_KEY: "fake_key"
PUBLISHABLE_KEY}afterSignOutUrl: string
afterSignOutUrl="/"> <JazzProvider> <
function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Element
function App(): React.JSX.Element
App /> </JazzProvider> </
function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Element
const ClerkProvider: React.ComponentType<ClerkProviderProps>
ClerkProvider> );
import {
SignInButton } from "@clerk/clerk-react"; import {
const SignInButton: { (props: Without<WithClerkProp<SignInButtonProps>, "clerk">): React.JSX.Element | null; displayName: string; }
function useAccount<A extends AccountClass<Account> | CoreAccountSchema, R extends ResolveQuery<A> = true>(AccountSchema?: A, options?: { resolve?: ResolveQueryStrict<A, R>; }): { me: Loaded<A, R> | undefined | null; agent: AnonymousJazzAgent | Loaded<A, true>; logOut: () => void; }
React hook for accessing the current user's account and authentication state. This hook provides access to the current user's account profile and root data, along with authentication utilities. It automatically handles subscription to the user's account data and provides a logout function.useAccount,function useIsAuthenticated(): boolean
useIsAuthenticated } from "jazz-tools/react"; export functionfunction AuthButton(): React.JSX.Element
AuthButton() { const {const logOut: () => void
logOut } =
useAccount<AccountClass<Account> | CoreAccountSchema<$ZodLooseShape>, true>(AccountSchema?: AccountClass<Account> | CoreAccountSchema<...> | undefined, options?: { ...; } | undefined): { ...; }
React hook for accessing the current user's account and authentication state. This hook provides access to the current user's account profile and root data, along with authentication utilities. It automatically handles subscription to the user's account data and provides a logout function.useAccount(); constconst isAuthenticated: boolean
isAuthenticated =function useIsAuthenticated(): boolean
useIsAuthenticated(); if (const isAuthenticated: boolean
isAuthenticated) { return <React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
buttonReact.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
onClick={() =>const logOut: () => void
logOut()}>Logout</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>; } return <SignInButton />; }
const SignInButton: { (props: Without<WithClerkProp<SignInButtonProps>, "clerk">): React.JSX.Element | null; displayName: string; }
Examples
You can explore Jazz with Clerk integration in our example projects. For more Clerk-specific demos, visit Clerk's documentation.
When to use Clerk
Clerk authentication is ideal when:
- You need an existing user management system
- You want to integrate with other Clerk features (roles, permissions)
- You require email/password authentication with verification
- You need OAuth providers (Google, GitHub, etc.)
- You want to avoid users having to manage passphrases
Limitations and considerations
- Online requirement: Initial signup/login requires internet connectivity
- Third-party dependency: Relies on Clerk's services for authentication
- Not fully local-first: Initial authentication requires a server
- Platform support: Not available on all platforms