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:

  1. Users sign up or sign in through Clerk's authentication system
  2. Jazz securely stores the user's account keys with Clerk
  3. When logging in, Jazz retrieves these keys from Clerk
  4. 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

We offer Clerk integration through our package: jazz-react-auth-clerk.

After installing, use <JazzProviderWithClerk /> to wrap your app:

import { const useClerk: () => LoadedClerkuseClerk, const ClerkProvider: React.ComponentType<ClerkProviderProps>ClerkProvider } from '@clerk/clerk-react';
import { 
const JazzProviderWithClerk: (props: {
    clerk: MinimalClerkClient;
} & JazzProviderProps) => JSX.Element | null
JazzProviderWithClerk
} from "jazz-react-auth-clerk";
function
function JazzProvider({ children }: {
    children: React.ReactNode;
}): React.JSX.Element
JazzProvider
({ children: React.ReactNodechildren }: { children: React.ReactNodechildren: React.type React.ReactNode = string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | null | undefined
Represents all of the things React can render. Where {@link ReactElement } only represents JSX, `ReactNode` represents everything that can be rendered.
@see{@link https://react-typescript-cheatsheet.netlify.app/docs/react-types/reactnode/ React TypeScript Cheatsheet}@example```tsx // Typing children type Props = { children: ReactNode } const Component = ({ children }: Props) => <div>{children}</div> <Component>hello</Component> ```@example```tsx // Typing a custom element type Props = { customElement: ReactNode } const Component = ({ customElement }: Props) => <div>{customElement}</div> <Component customElement={<div>hello</div>} /> ```
ReactNode
}) {
const const clerk: LoadedClerkclerk = function useClerk(): LoadedClerkuseClerk(); return ( <
const JazzProviderWithClerk: (props: {
    clerk: MinimalClerkClient;
} & JazzProviderProps) => JSX.Element | null
JazzProviderWithClerk
clerk: 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"apiKey}`, }} > {children: React.ReactNodechildren} </
const JazzProviderWithClerk: (props: {
    clerk: MinimalClerkClient;
} & JazzProviderProps) => JSX.Element | null
JazzProviderWithClerk
>
); } function createRoot(container: Container, options?: RootOptions): Root
createRoot lets you create a root to display React components inside a browser DOM node.
@see{@link https://react.dev/reference/react-dom/client/createRoot API Reference for `createRoot`}
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.
@paramelementId String that specifies the ID value.
getElementById
("root")!).Root.render(children: React.ReactNode): voidrender(
<const ClerkProvider: React.ComponentType<ClerkProviderProps>ClerkProvider publishableKey: string
The Clerk publishable key for your instance
@noteThis can be found in your Clerk Dashboard on the [API Keys](https://dashboard.clerk.com/last-active?path=api-keys) page
publishableKey
={const PUBLISHABLE_KEY: "fake_key"PUBLISHABLE_KEY} afterSignOutUrl: stringafterSignOutUrl="/">
<
function JazzProvider({ children }: {
    children: React.ReactNode;
}): React.JSX.Element
JazzProvider
>
<function App(): React.JSX.ElementApp /> </
function JazzProvider({ children }: {
    children: React.ReactNode;
}): React.JSX.Element
JazzProvider
>
</const ClerkProvider: React.ComponentType<ClerkProviderProps>ClerkProvider> );

Once set up, you can use Clerk's auth methods for login and signup:

import { 
const SignInButton: {
    (props: Without<WithClerkProp<SignInButtonProps>, "clerk">): React.JSX.Element | null;
    displayName: string;
}
SignInButton
} from "@clerk/clerk-react";
import {
function useAccount<A extends RegisteredAccount>(): {
    me: A;
    logOut: () => void;
} (+1 overload)
useAccount
, function useIsAuthenticated(): booleanuseIsAuthenticated } from "jazz-react";
export function function AuthButton(): React.JSX.ElementAuthButton() { const { const logOut: () => voidlogOut } =
useAccount<Account>(): {
    me: Account;
    logOut: () => void;
} (+1 overload)
useAccount
();
const const isAuthenticated: booleanisAuthenticated = function useIsAuthenticated(): booleanuseIsAuthenticated(); if (const isAuthenticated: booleanisAuthenticated) { return <JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefinedonClick={() => const logOut: () => voidlogOut()}>Logout</JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button>; } return <
const SignInButton: {
    (props: Without<WithClerkProp<SignInButtonProps>, "clerk">): React.JSX.Element | null;
    displayName: string;
}
SignInButton
/>;
}

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

Additional resources