Skip to content

Conversation

@panteliselef
Copy link
Member

@panteliselef panteliselef commented Nov 21, 2025

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • Bug Fixes

    • Disabled automatic query retries and optimized refetch behaviors to improve application reliability.
  • Chores

    • Updated dependency management system using catalog-based resolution for query libraries.
    • Refactored internal query client initialization for better performance.

✏️ Tip: You can customize this high-level summary in your review settings.

@panteliselef panteliselef self-assigned this Nov 21, 2025
@changeset-bot
Copy link

changeset-bot bot commented Nov 21, 2025

🦋 Changeset detected

Latest commit: fab9ef2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-js Patch
@clerk/shared Patch
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/types Patch
@clerk/vue Patch
@clerk/localizations Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Nov 21, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Nov 21, 2025 5:54pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 21, 2025

Walkthrough

This patch introduces deferred initialization of TanStack Query Client with explicit configuration to disable retries and refetch behaviors, migrates dependencies to pnpm catalog-based resolution for @tanstack/query-core, and refactors the query client hook to use event-driven state management for asynchronous client availability.

Changes

Cohort / File(s) Summary
Dependency catalog and resolution
pnpm-workspace.yaml, packages/clerk-js/package.json, packages/shared/package.json
Introduced pnpm catalog entry tanstack for @tanstack/query-core v5.87.4; updated both clerk-js and shared packages to reference the catalog alias "catalog:tanstack" instead of static version.
Changeset entry
.changeset/thirty-pears-reply.md
Added changeset patching @clerk/clerk-js and @clerk/shared with note to disable retry in queryClient.
QueryClient initialization and configuration
packages/clerk-js/src/core/clerk.ts
Introduced deferred QueryClient initialization via private #initQueryClient method with lazy-loading of query-core; added clerkQueryClientConfig with retry, refetchOnWindowFocus, and refetchOnReconnect disabled; replaced direct instantiation with tagged ClerkRQClient wrapper; emits ready status via public event bus.
Test client configuration
packages/clerk-js/src/test/mock-helpers.ts
Updated defaultQueryClient with three refetch-disabling flags: refetchOnWindowFocus, refetchOnReconnect, and refetchOnMount all set to false.
Query client hook refactoring
packages/shared/src/react/clerk-rq/use-clerk-query-client.ts
Introduced internal helpers (ClerkRQClient type, isTaggedRQClient guard, getQueryClientState resolver); refactored hook to subscribe to clerk.queryClientStatus event and manage state via event listener instead of direct property access; maintains same public signature.

Sequence Diagram

sequenceDiagram
    participant Component as React Component
    participant Hook as useClerkQueryClient
    participant Clerk as Clerk Instance
    participant QueryClient as QueryClient (lazy)
    
    Component->>Hook: Call useClerkQueryClient()
    Hook->>Clerk: Subscribe to queryClientStatus event
    Note over Clerk: Initial state: client uninitialized
    Hook->>Hook: Local state: {client: null, isLoaded: false}
    Component->>Component: Render with isLoaded=false
    
    Note over Clerk: First access to __internal_queryClient
    Clerk->>Clerk: Call `#initQueryClient`()
    Clerk->>QueryClient: Lazy-load `@tanstack/query-core`<br/>Create QueryClient with config<br/>(retry disabled, refetch disabled)
    QueryClient-->>Clerk: QueryClient ready
    Clerk->>Clerk: Emit queryClientStatus = "ready"
    
    Clerk-->>Hook: Status change event
    Hook->>Clerk: getQueryClientState(clerk)
    Hook->>Hook: Update state: {client, isLoaded: true}
    Hook->>Component: Return updated state
    Component->>Component: Re-render with isLoaded=true
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring extra attention:

  • Logic in packages/clerk-js/src/core/clerk.ts around deferred initialization, lazy-loading of query-core, and event emission via the public event bus; verify that #initQueryClient is thread-safe and doesn't race with multiple accesses to __internal_queryClient.
  • State management refactoring in packages/shared/src/react/clerk-rq/use-clerk-query-client.ts; confirm that event listener cleanup prevents memory leaks and that getQueryClientState correctly resolves the tagged client and loading status.
  • Verify consistency of QueryClient configuration (retry disabled, specific refetch flags) across clerk-js production code and test mocks.
  • Confirm that the catalog-based dependency resolution in pnpm-workspace.yaml is correctly propagated to both packages.

Poem

🐰 A query dances, now deferred with care,
Retries pause, refetches cease their flight,
Catalogs align the tanstack affairs,
States bloom through events in the night,
Lazy loading hops—ready at last!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: configuring default query client options across the shared and clerk-js packages using catalog-based dependency management.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch elef/consolidate-query-client-settings

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 21, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7285

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7285

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7285

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7285

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7285

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7285

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7285

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@7285

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7285

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7285

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7285

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7285

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7285

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7285

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@7285

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7285

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7285

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7285

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7285

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7285

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7285

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7285

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7285

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7285

commit: fab9ef2

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/shared/src/react/clerk-rq/use-clerk-query-client.ts (1)

62-69: Consider strengthening the type guard to validate the client property.

The isTaggedRQClient type guard checks for the __tag property but doesn't verify that the client property exists or is a QueryClient. While this is likely safe given internal usage, adding a validation for the client property would make the guard more robust.

Apply this diff to strengthen the type guard:

 const isTaggedRQClient = (value: unknown): value is ClerkRQClient => {
   return (
     typeof value === 'object' &&
     value !== null &&
     '__tag' in (value as Record<string, unknown>) &&
-    (value as Record<string, unknown>).__tag === 'clerk-rq-client'
+    (value as Record<string, unknown>).__tag === 'clerk-rq-client' &&
+    'client' in (value as Record<string, unknown>)
   );
 };
packages/clerk-js/src/core/clerk.ts (1)

299-316: Consider adding error handling for query client initialization.

The #initQueryClient method uses a fire-and-forget pattern with dynamic import but doesn't handle initialization failures. If the import fails or the QueryClient constructor throws, the #queryClient remains undefined and the queryClientStatus event is never emitted, leaving consumers in a perpetual loading state.

Apply this diff to add error handling:

 #initQueryClient = (): void => {
   if (this.#queryClient) {
     return;
   }
 
   void import('./query-core')
     .then(module => module.QueryClient)
     .then(QueryClientCtor => {
       if (this.#queryClient) {
         return;
       }
 
       this.#queryClient = new QueryClientCtor(clerkQueryClientConfig);
 
       // @ts-expect-error - queryClientStatus is not typed
       this.#publicEventBus.emit('queryClientStatus', 'ready');
+    })
+    .catch(error => {
+      // Log initialization failure but don't throw
+      console.error('Failed to initialize query client:', error);
+      // Optionally emit error event
+      // @ts-expect-error - queryClientStatus is not typed
+      this.#publicEventBus.emit('queryClientStatus', 'error');
     });
 };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 69833fe and fab9ef2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .changeset/thirty-pears-reply.md (1 hunks)
  • packages/clerk-js/package.json (1 hunks)
  • packages/clerk-js/src/core/clerk.ts (4 hunks)
  • packages/clerk-js/src/test/mock-helpers.ts (1 hunks)
  • packages/shared/package.json (1 hunks)
  • packages/shared/src/react/clerk-rq/use-clerk-query-client.ts (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/clerk-js/src/core/clerk.ts (1)
packages/clerk-js/src/core/query-core.ts (1)
  • QueryClient (3-3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (9)
packages/shared/src/react/clerk-rq/use-clerk-query-client.ts (2)

71-79: LGTM!

The getQueryClientState function correctly handles both the initialized and uninitialized query client states, providing a mock client when the real one isn't ready yet.


81-101: LGTM!

The event-driven approach for tracking query client initialization is well-implemented:

  • Initial state is correctly derived
  • Event subscription properly updates state
  • Cleanup prevents memory leaks
  • Falls back to mock client when not loaded
packages/shared/package.json (1)

166-166: LGTM!

The migration to catalog-based resolution for @tanstack/query-core aligns with the new catalog entry in pnpm-workspace.yaml and maintains version consistency.

pnpm-workspace.yaml (1)

21-23: LGTM!

The new catalog entry for TanStack Query provides centralized version management across the workspace, which is a best practice for monorepos.

packages/clerk-js/src/test/mock-helpers.ts (1)

58-60: LGTM!

Disabling refetch behaviors in test configuration improves test determinism and prevents flaky tests caused by automatic query refetches. This aligns with the production query client configuration.

packages/clerk-js/package.json (1)

74-74: LGTM!

The migration to catalog-based resolution maintains version consistency across the workspace and aligns with the catalog entry in pnpm-workspace.yaml.

packages/clerk-js/src/core/clerk.ts (3)

97-97: LGTM!

The type-only imports and discriminated union pattern using RQ_CLIENT_TAG are well-designed and enable proper tree-shaking while maintaining type safety.

Also applies to: 201-203


205-217: LGTM!

The query client configuration is well-thought-out:

  • Disables retry to use fapiClient's existing retry logic
  • Disables automatic refetch on window focus/reconnect to reduce unnecessary requests
  • Enables refetch on mount for stale data
  • Clear comments explain the design decisions

264-273: LGTM!

The getter pattern ensures lazy initialization while protecting against re-initialization via the guard in #initQueryClient. Returns undefined safely when the client isn't ready yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants