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: () => LoadedClerkuseClerk,const ClerkProvider: React.ComponentType<ClerkProviderProps>ClerkProvider } from '@clerk/clerk-react'; import {JazzReactProviderWithClerk } from "jazz-tools/react"; functionconst JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<...> | Iterable<React.ReactNode> | null | undefined> | JSX.Element | nullJazzProvider({function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Elementchildren: React.ReactNodechildren }: {children: React.ReactNodechildren: React.type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<...> | null | undefinedRepresents all of the things React can render. Where {@link ReactElement } only represents JSX, `ReactNode` represents everything that can be rendered.ReactNode }) { constconst clerk: LoadedClerkclerk =function useClerk(): LoadedClerkuseClerk(); return ( <JazzReactProviderWithClerkconst JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<...> | Iterable<React.ReactNode> | null | undefined> | JSX.Element | nullclerk: MinimalClerkClientclerk={const clerk: LoadedClerkclerk}sync: SyncConfigsync={{peer: "wss://cloud.jazz.tools/?key=you@example.com"peer: `wss://cloud.jazz.tools/?key=${const apiKey: "you@example.com"Use your email as a temporary key, or get a free API Key at dashboard.jazz.tools for higher limits.apiKey}`, }} > {children: React.ReactNodechildren} </JazzReactProviderWithClerk> ); }const JazzReactProviderWithClerk: <S extends (AccountClass<Account> & CoValueFromRaw<Account>) | CoreAccountSchema>(props: { clerk: MinimalClerkClient; } & JazzProviderProps<S>) => string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<...> | Iterable<React.ReactNode> | null | undefined> | JSX.Element | nullfunction createRoot(container: Container, options?: RootOptions): RootcreateRoot 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 | nullReturns a reference to the first object with the specified value of the ID attribute.getElementById("root")!).Root.render(children: React.ReactNode): voidrender( <const ClerkProvider: React.ComponentType<ClerkProviderProps>ClerkProviderpublishableKey: stringThe Clerk publishable key for your instancepublishableKey={const PUBLISHABLE_KEY: "fake_key"PUBLISHABLE_KEY}afterSignOutUrl: stringafterSignOutUrl="/"> <JazzProvider> <function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Elementfunction App(): React.JSX.ElementApp /> </JazzProvider> </function JazzProvider({ children }: { children: React.ReactNode; }): React.JSX.Elementconst 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 useIsAuthenticated(): booleanuseIsAuthenticated,function useLogOut(): () => voidReturns a function for logging out of the current account.useLogOut } from "jazz-tools/react"; export functionfunction AuthButton(): React.JSX.ElementAuthButton() { constconst logOut: () => voidlogOut =function useLogOut(): () => voidReturns a function for logging out of the current account.useLogOut(); constconst isAuthenticated: booleanisAuthenticated =function useIsAuthenticated(): booleanuseIsAuthenticated(); if (const isAuthenticated: booleanisAuthenticated) { return <React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>buttonReact.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefinedonClick={() =>const logOut: () => voidlogOut()}>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