Skip to content

Conversation

@alexcarpenter
Copy link
Member

@alexcarpenter alexcarpenter commented Jul 21, 2025

Description

Refactor base theme approach to enable opting into simple theme.

appearance={{
  theme: 'clerk' // default
}}

// is equal to 

appearance={{}}
appearance={{
  theme: 'simple' // removes clerk base theme
}}
import { dark } from '@clerk/themes'

appearance={{
  theme: dark
}}

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

  • New Features

    • Introduced support for a new theme property in appearance customization, enabling selection between "clerk" and "simple" themes, with backward compatibility for the deprecated baseTheme property.
    • Added a minimal "simple" theme option alongside the existing theme.
  • Enhancements

    • Improved focus styles for action and social buttons, including visual focus rings and hover-as-focus behavior.
    • Updated border colors across various UI components (cards, drawers, menus, tables, popovers) for increased contrast and clarity.
    • Removed box shadows from several components for a cleaner, flatter appearance.
    • Adjusted spacing and margins in card and popover components for more consistent layout.
  • Bug Fixes

    • Enhanced merging logic for appearance variables to better preserve customizations.
  • Documentation

    • Updated type documentation and examples to clarify usage of new and deprecated appearance properties.
  • Tests

    • Added and updated tests to cover new theme selection flows and ensure backward compatibility.

Changed border color from $borderAlpha100 to $borderAlpha150 across Card, PopoverCard, ProfileCardContent, Button, and Table components for improved visual consistency. Also added hoverAsFocus prop to SocialButtonBlock and refined focus/hover styles in Button.
Changed border colors in ActionCard and MenuList components to use $borderAlpha150 for improved visual consistency. Removed boxShadow styles from ActionCard and MenuList. Minor formatting adjustment in Button focus style.
Added the focusRing prop to several action buttons in OrganizationSwitcherPopover and SessionActions components to improve keyboard accessibility and visual focus indication.
@changeset-bot
Copy link

changeset-bot bot commented Jul 21, 2025

🦋 Changeset detected

Latest commit: 320e592

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 Minor
@clerk/types Minor
@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/localizations Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/shared Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue 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 Jul 21, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 25, 2025 8:09pm

Introduces support for setting `baseTheme: false` in appearance and globalAppearance, allowing users to disable the default base theme. Updates tests, documentation, and internal logic to handle the new option and renames `polishedAppearance` to `baseTheme` for clarity.
Changed border color references from $borderAlpha100 to $borderAlpha150 in PricingTableDefault and Drawer components for improved visual consistency.
Introduces 'clerk' and 'simple' string-based themes and a getBaseTheme function to select them. Updates the Theme type to support a new 'theme' property, deprecates 'baseTheme', and refactors theme expansion logic to use the new property. This enables easier theme selection and future extensibility.
Refactored parseCaptcha to only merge defined captcha properties (theme, size, language) from appearance objects, preventing undefined values from overwriting defaults.
Expanded and refactored tests for AppearanceProvider to cover new theme and captcha properties, including support for string, object, and array-based themes. Updated type documentation to remove mention of disabling baseTheme with 'false', reflecting deprecation and new theme precedence.
@alexcarpenter alexcarpenter changed the title spike(clerk-js): Refactor base theme approach refactor(clerk-js,types): Refactor base theme approach Jul 25, 2025
Added an empty elements object to simpleTheme in baseTheme.ts. Updated parseAppearance.test.tsx to expect two parsed elements (simple theme and base theme) instead of one, reflecting changes in theme composition.
Adds border color to button focus state when hoverAsFocus is enabled, improving visual feedback. Also enables hoverAsFocus for SocialButtonIcon.
@alexcarpenter alexcarpenter marked this pull request as ready for review July 25, 2025 18:30
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 25, 2025

📝 Walkthrough

Walkthrough

This change set introduces a new theming mechanism for UI components, replacing the previous baseTheme property with a new theme property that supports both string-based and object-based themes, including arrays. The default and simple themes are now accessible via getBaseTheme, and the type definitions have been updated to allow 'clerk' and 'simple' as valid theme values. The codebase is refactored to use the new theme system, with baseTheme marked as deprecated. Additionally, numerous UI components have their border color opacities increased and box shadows removed to adjust visual styling. Some components gain new props for focus and hover behavior, and related test suites are updated to verify the new theme logic.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Complexity label: Complex
Rationale:

  • The update spans several core files, including type definitions, theming logic, UI component styling, and test suites.
  • It introduces a new public API (theme), deprecates an old one (baseTheme), and updates the internal logic to support both.
  • Multiple UI components are visually restyled, affecting the consistency and appearance of the product.
  • Test coverage is expanded to ensure the new theming system works as intended.
  • The changes require careful review for backward compatibility, correct type usage, and consistent application of new styles and props.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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/clerk-js/sandbox/app.ts (1)

354-356: Commented code for testing theme configurations.

The commented-out appearance configuration suggests testing of different theme options during development. Consider removing this commented code if it's no longer needed for testing.

packages/clerk-js/src/ui/baseTheme.ts (1)

270-274: Clarify the non-public API usage.

The simpleStyles property uses a TypeScript suppression comment indicating it's "not public api". Consider documenting why this internal property is necessary and whether there's a more type-safe approach.

const simpleTheme: Appearance = {
-  //@ts-expect-error not public api
+  // Internal property to indicate simple styling mode
+  //@ts-expect-error Internal API for simple theme detection
  simpleStyles: true,
  elements: {},
} satisfies Appearance;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92dfd80 and 59c66af.

📒 Files selected for processing (18)
  • packages/clerk-js/sandbox/app.ts (2 hunks)
  • packages/clerk-js/src/ui/baseTheme.ts (2 hunks)
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx (2 hunks)
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx (3 hunks)
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx (2 hunks)
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx (3 hunks)
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts (5 hunks)
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/Drawer.tsx (2 hunks)
  • packages/clerk-js/src/ui/elements/Menu.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx (1 hunks)
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx (2 hunks)
  • packages/clerk-js/src/ui/primitives/Button.tsx (1 hunks)
  • packages/clerk-js/src/ui/primitives/Table.tsx (3 hunks)
  • packages/types/src/appearance.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
packages/clerk-js/src/ui/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/clerk-js-ui.mdc)

packages/clerk-js/src/ui/**/*.{ts,tsx}: Element descriptors should always be camelCase
Use element descriptors in UI components to enable consistent theming and styling via appearance.elements
Element descriptors should generate unique, stable CSS classes for theming
Element descriptors should handle state classes (e.g., cl-loading, cl-active, cl-error, cl-open) automatically based on component state
Do not render hard-coded values; all user-facing strings must be localized using provided localization methods
Use the useLocalizations hook and localizationKeys utility for all text and error messages
Use the styled system (sx prop, theme tokens, responsive values) for custom component styling
Use useCardState for card-level state, useFormState for form-level state, and useLoadingStatus for loading states
Always use handleError utility for API errors and use translateError for localized error messages
Use useFormControl for form field state, implement proper validation, and handle loading and error states in forms
Use localization keys for all form labels and placeholders
Use element descriptors for consistent styling and follow the theme token system
Use the Card and FormContainer patterns for consistent UI structure

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
**/*.{jsx,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

**/*.{jsx,tsx}: Use error boundaries in React components
Minimize re-renders in React components

**/*.{jsx,tsx}: Always use functional components with hooks instead of class components
Follow PascalCase naming for components: UserProfile, NavigationMenu
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Use useState for simple state management
Use useReducer for complex state logic
Implement proper state initialization
Use proper state updates with callbacks
Implement proper state cleanup
Use Context API for theme/authentication
Implement proper state selectors
Use proper state normalization
Implement proper state persistence
Use React.memo for expensive components
Implement proper useCallback for handlers
Use proper useMemo for expensive computations
Implement proper virtualization for lists
Use proper code splitting with React.lazy
Implement proper cleanup in useEffect
Use proper refs for DOM access
Implement proper event listener cleanup
Use proper abort controllers for fetch
Implement proper subscription cleanup
Use proper HTML elements
Implement proper ARIA attributes
Use proper heading hierarchy
Implement proper form labels
Use proper button types
Implement proper focus management
Use proper keyboard shortcuts
Implement proper tab order
Use proper skip links
Implement proper focus traps
Implement proper error boundaries
Use proper error logging
Implement proper error recovery
Use proper error messages
Implement proper error fallbacks
Use proper form validation
Implement proper error states
Use proper error messages
Implement proper form submission
Use proper form reset
Use proper component naming
Implement proper file naming
Use proper prop naming
Implement proper...

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
**/*.tsx

📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)

**/*.tsx: Use proper type definitions for props and state
Leverage TypeScript's type inference where possible
Use proper event types for handlers
Implement proper generic types for reusable components
Use proper type guards for conditional rendering

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
**/*

⚙️ CodeRabbit Configuration File

**/*: If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.

Whenever reviewing a pull request, if there are any changes that could impact security, always tag @clerk/security in the PR.

Security-impacting changes include, but are not limited to:

  • Changes to authentication logic or mechanisms (e.g. login, session handling, token issuance)
  • Any modification to access control, authorization checks, or role-based permissions
  • Introduction or modification of hashing algorithms, signature verification, or cryptographic primitives
  • Handling of sensitive data (e.g. passwords, tokens, secrets, PII)
  • Integration with external identity providers (e.g. SSO, OAuth, OpenID Connect)
  • Modifications to security headers, cookie flags, CORS policies, or CSRF protections
  • Bypass mechanisms (e.g. feature flags, testing overrides) that could weaken protections
  • Changes to rate limiting, abuse prevention, or input validation

If you're unsure whether a change is security-relevant, err on the side of caution and tag @clerk/security.

Any time that you tag @clerk/security, please do so explicitly in a code comment, rather than within a collapsed section in a coderabbit comment, such as the "recent review details" section. If you do use the team name in any thinking or non-direct-code-comment content, it can be referred to as "clerk security team" to avoid accidentally printing the tag which sends a notification to the team.

Files:

  • packages/clerk-js/src/ui/elements/Menu.tsx
  • packages/clerk-js/sandbox/app.ts
  • packages/clerk-js/src/ui/elements/Card/CardRoot.tsx
  • packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx
  • packages/clerk-js/src/ui/elements/Drawer.tsx
  • packages/clerk-js/src/ui/elements/SocialButtons.tsx
  • packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx
  • packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx
  • packages/clerk-js/src/ui/elements/PopoverCard.tsx
  • packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
  • packages/clerk-js/src/ui/baseTheme.ts
  • packages/clerk-js/src/ui/primitives/Table.tsx
  • packages/clerk-js/src/ui/primitives/Button.tsx
  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
  • packages/clerk-js/src/ui/customizables/parseAppearance.ts
  • packages/clerk-js/src/ui/elements/Action/ActionCard.tsx
  • packages/clerk-js/src/ui/elements/Card/CardContent.tsx
  • packages/types/src/appearance.ts
packages/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)

Unit tests should use Jest or Vitest as the test runner.

Files:

  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
packages/{clerk-js,elements,themes}/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)

Visual regression testing should be performed for UI components.

Files:

  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
**/*.test.{jsx,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)

**/*.test.{jsx,tsx}: Use React Testing Library
Test component behavior, not implementation
Use proper test queries
Implement proper test isolation
Use proper test coverage
Test component interactions
Use proper test data
Implement proper test setup
Use proper test cleanup
Implement proper test assertions
Use proper test structure

Files:

  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx
packages/types/src/appearance.ts

📄 CodeRabbit Inference Engine (.cursor/rules/clerk-js-ui.mdc)

Add new element descriptor types in packages/types/src/appearance.ts before using them elsewhere

Files:

  • packages/types/src/appearance.ts
🧬 Code Graph Analysis (2)
packages/clerk-js/src/ui/baseTheme.ts (1)
packages/types/src/appearance.ts (1)
  • Appearance (986-1052)
packages/clerk-js/src/ui/customizables/parseAppearance.ts (2)
packages/clerk-js/src/ui/baseTheme.ts (2)
  • baseTheme (286-286)
  • getBaseTheme (276-284)
packages/types/src/appearance.ts (2)
  • Theme (811-860)
  • CaptchaAppearanceOptions (941-957)
⏰ 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). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (28)
packages/clerk-js/src/ui/elements/Action/ActionCard.tsx (1)

32-32: Visual refinement approved.

The border color opacity increase from $borderAlpha100 to $borderAlpha150 improves visual clarity and aligns with the broader UI styling updates across components.

packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx (1)

185-185: Accessibility improvement approved.

Adding focusRing props to the SmallAction components enhances keyboard navigation and focus visibility for the manage account and sign out actions.

Also applies to: 197-197

packages/clerk-js/src/ui/elements/SocialButtons.tsx (1)

214-214: UI interaction enhancement approved.

Adding hoverAsFocus props to both social button variants creates consistent hover and focus behavior across social authentication options, improving user experience.

Also applies to: 237-237

packages/clerk-js/src/ui/elements/Menu.tsx (1)

133-133: Menu styling refinement approved.

The border color change from $borderAlpha50 to $borderAlpha150 significantly improves menu visibility and aligns with the coordinated visual updates across the UI component library.

packages/clerk-js/src/ui/elements/Card/CardRoot.tsx (1)

43-43: Card styling enhancement approved.

The border color update from $borderAlpha100 to $borderAlpha150 improves the visual definition of card boundaries, contributing to better content organization and visual hierarchy.

packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcherPopover.tsx (1)

120-120: LGTM! Good accessibility improvement.

Adding the focusRing prop to both SmallAction components enhances keyboard navigation and focus visibility, which aligns with accessibility best practices.

Also applies to: 129-129

packages/clerk-js/src/ui/elements/Drawer.tsx (1)

267-267: LGTM! Consistent styling update.

The border color updates from $borderAlpha100 to $borderAlpha150 align with the coordinated visual refresh across the UI components, providing better visual definition and consistency.

Also applies to: 306-306

packages/clerk-js/src/ui/elements/ProfileCard/ProfileCardContent.tsx (1)

44-46: LGTM! Consistent styling refinement.

The border color update to $borderAlpha150 and the negative margins align with the broader UI refresh. The negative margins likely help with proper border alignment when components are positioned adjacently.

packages/clerk-js/sandbox/app.ts (1)

195-196: Good backward compatibility enhancement.

Preserving existing appearance properties when updating variables ensures that configurations like baseTheme are maintained, supporting the new theming approach while maintaining backward compatibility.

packages/clerk-js/src/ui/elements/PopoverCard.tsx (1)

61-63: LGTM! Coordinated styling update.

The border color update to $borderAlpha150 and negative margins align with the broader UI refresh across components. These changes improve visual consistency and proper border alignment.

packages/clerk-js/src/ui/primitives/Table.tsx (1)

16-16: LGTM! Consistent border opacity improvements.

The border color changes from $borderAlpha100 to $borderAlpha150 provide improved visual consistency across the table component. These styling updates align with the broader theme refinements described in the PR objectives.

Also applies to: 25-25, 36-36, 48-48

packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx (1)

172-172: LGTM! Consistent border styling improvements.

The border color updates from $borderAlpha100 to $borderAlpha150 across the card, features section, and footer provide better visual definition and consistency with the theme refactor.

Also applies to: 207-207, 227-227

packages/clerk-js/src/ui/elements/Card/CardContent.tsx (2)

42-42: LGTM! Border color improvement aligns with theme updates.

The border color change from $borderAlpha50 to $borderAlpha150 provides better visual consistency with the broader theme refactor.


48-49: Verify that negative margins don't cause layout issues.

The addition of negative margins (marginBlockStart: '-1px' and marginInline: '-1px') appears to be related to the border changes, but negative margins can sometimes cause unexpected layout behaviors or overlapping elements.

Please ensure these negative margins are necessary and don't introduce visual artifacts or layout issues across different use cases of the CardContent component.

packages/clerk-js/src/ui/baseTheme.ts (1)

96-96: LGTM! Clean implementation of the new theme system.

The refactor from polishedAppearance to clerkTheme, addition of getBaseTheme function, and baseTheme export properly implement the new theming mechanism described in the PR objectives. This enables users to explicitly opt into different themes while maintaining backward compatibility.

Also applies to: 276-286

packages/clerk-js/src/ui/customizables/__tests__/parseAppearance.test.tsx (2)

341-341: LGTM! Test descriptions updated to reflect API changes.

The test descriptions correctly reflect the renaming from polishedAppearance to baseTheme.

Also applies to: 362-362


468-587: Excellent test coverage for the new theme system!

The comprehensive test suite covers all the key scenarios from the PR objectives:

  • String-based theme support ('clerk' and 'simple')
  • Theme property precedence over deprecated baseTheme
  • Backward compatibility with existing baseTheme usage
  • Object and array-based theme support

The test assertions properly verify both the new functionality and maintain backward compatibility. This thorough testing gives confidence in the theme refactor implementation.

packages/clerk-js/src/ui/customizables/parseAppearance.ts (5)

4-4: LGTM! Import changes align with new theme architecture.

The change from importing polishedAppearance to baseTheme, getBaseTheme is consistent with the new centralized theme handling approach described in the PR objectives.


24-24: Correct addition of 'theme' to omitted keys.

Adding 'theme' to the PublicAppearanceTopLevelKey omission list is appropriate since it's now handled specially in the parsing logic, similar to baseTheme.


86-86: LGTM! Consistent use of new baseTheme export.

The replacement of polishedAppearance with baseTheme maintains the same functionality while using the new centralized theme exports.


107-118: Excellent implementation of new theme handling.

This implementation properly handles the new theme system with:

  • Backward compatibility via fallback to deprecated baseTheme
  • Support for string-based themes ('clerk', 'simple') via getBaseTheme
  • Support for object-based and array-based themes
  • Proper recursive expansion for nested themes

The logic correctly prioritizes the new theme property while maintaining compatibility.


134-146: Improved CAPTCHA appearance merging logic.

The selective property copying approach is better than the previous shallow merge as it:

  • Explicitly handles only the expected properties (theme, size, language)
  • Avoids copying undefined values
  • Makes the merging behavior more predictable and maintainable
packages/types/src/appearance.ts (4)

809-809: Correct expansion of BaseTheme type for string-based themes.

The union type properly enables both object-based themes (BaseThemeTaggedType) and the new string-based themes ('clerk' | 'simple') while maintaining the optional cssLayerName property.


813-826: Excellent documentation and type definition for new theme property.

The new theme property is well-documented with:

  • Clear examples for both object-based and string-based usage
  • Proper JSDoc formatting
  • Support for both single themes and arrays
  • Comprehensive explanation of the functionality

828-835: Proper deprecation of baseTheme with migration guidance.

The deprecation is handled correctly with:

  • Clear deprecation notice
  • Explicit migration path to use theme instead
  • Maintained backward compatibility in the type definition

857-857: Improved clarity in captcha example.

The example change from theme: 'dark' to captcha: { theme: 'dark' } better illustrates the correct usage of the captcha property structure.

packages/clerk-js/src/ui/primitives/Button.tsx (2)

98-98: Improved border visibility with increased opacity.

The change to theme.colors.$borderAlpha150 increases border opacity for better visual definition, consistent with the broader UI styling refresh across multiple components.

Also applies to: 108-108


101-103: Enhanced focus styles for better accessibility.

The addition of borderColor: theme.colors.$borderAlpha300 in focus states when hoverAsFocus is true improves accessibility by providing clearer visual feedback during keyboard navigation.

Also applies to: 112-114

@tmilewski
Copy link
Member

@alexcarpenter The one nit from CodeRabbit makes sense:

const simpleTheme: Appearance = {
-  //@ts-expect-error not public api
+  // Internal property to indicate simple styling mode
+  //@ts-expect-error Internal API for simple theme detection
  simpleStyles: true,
  elements: {},
} satisfies Appearance;

Co-authored-by: Tom Milewski <me@tm.codes>
Updated the comment above the ts-expect-error directive in simpleTheme to clarify that it is for internal API usage related to simple theme detection.
Updated processCssLayerNameExtraction to handle both the new 'theme' property and the deprecated 'baseTheme' property in the Appearance object. The function now extracts cssLayerName from either property, supports arrays and string themes, and ensures backward compatibility.
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jul 25, 2025

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/elements

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

@clerk/clerk-expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/clerk-react

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

@clerk/react-router

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

@clerk/remix

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/themes

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

@clerk/types

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

@clerk/upgrade

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

@clerk/vue

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

commit: 320e592

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/clerk-js/src/utils/appearance.ts (2)

22-51: Consider optimizing cssLayerName extraction for better performance.

The array handling logic is correct and properly handles both string and object themes. However, the forEach loop could be more efficient.

Consider using find() for early termination once the first cssLayerName is found:

-    themeProperty.forEach((theme: BaseTheme) => {
-      if (!cssLayerNameFromTheme && typeof theme === 'object' && theme.cssLayerName) {
-        cssLayerNameFromTheme = theme.cssLayerName;
-      }
-    });
+    const themeWithCssLayer = themeProperty.find((theme: BaseTheme) => 
+      typeof theme === 'object' && theme.cssLayerName
+    );
+    cssLayerNameFromTheme = typeof themeWithCssLayer === 'object' ? themeWithCssLayer.cssLayerName : undefined;

62-68: Simplify the theme processing logic.

The IIFE pattern works but can be simplified for better readability.

Consider this cleaner approach:

-    const processedTheme =
-      typeof themeProperty === 'string'
-        ? themeProperty
-        : (() => {
-            const { cssLayerName, ...rest } = themeProperty;
-            return rest;
-          })();
+    let processedTheme: BaseTheme;
+    if (typeof themeProperty === 'string') {
+      processedTheme = themeProperty;
+    } else {
+      const { cssLayerName, ...rest } = themeProperty;
+      processedTheme = rest;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff3f794 and 320e592.

📒 Files selected for processing (1)
  • packages/clerk-js/src/utils/appearance.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/clerk-js/src/utils/appearance.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/src/utils/appearance.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/clerk-js/src/utils/appearance.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/clerk-js/src/utils/appearance.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/clerk-js/src/utils/appearance.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/clerk-js/src/utils/appearance.ts
**/*

⚙️ CodeRabbit Configuration File

**/*: If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.

Whenever reviewing a pull request, if there are any changes that could impact security, always tag @clerk/security in the PR.

Security-impacting changes include, but are not limited to:

  • Changes to authentication logic or mechanisms (e.g. login, session handling, token issuance)
  • Any modification to access control, authorization checks, or role-based permissions
  • Introduction or modification of hashing algorithms, signature verification, or cryptographic primitives
  • Handling of sensitive data (e.g. passwords, tokens, secrets, PII)
  • Integration with external identity providers (e.g. SSO, OAuth, OpenID Connect)
  • Modifications to security headers, cookie flags, CORS policies, or CSRF protections
  • Bypass mechanisms (e.g. feature flags, testing overrides) that could weaken protections
  • Changes to rate limiting, abuse prevention, or input validation

If you're unsure whether a change is security-relevant, err on the side of caution and tag @clerk/security.

Any time that you tag @clerk/security, please do so explicitly in a code comment, rather than within a collapsed section in a coderabbit comment, such as the "recent review details" section. If you do use the team name in any thinking or non-direct-code-comment content, it can be referred to as "clerk security team" to avoid accidentally printing the tag which sends a notification to the team.

Files:

  • packages/clerk-js/src/utils/appearance.ts
🧬 Code Graph Analysis (1)
packages/clerk-js/src/utils/appearance.ts (1)
packages/types/src/appearance.ts (2)
  • Appearance (986-1052)
  • BaseTheme (809-809)
🔇 Additional comments (2)
packages/clerk-js/src/utils/appearance.ts (2)

3-18: LGTM! Clean backward compatibility implementation.

The JSDoc documentation clearly explains the dual property support, and the logic correctly prioritizes the new theme property while maintaining backward compatibility with baseTheme. The early return logic is sound.


7-84: Test coverage located in appearance.spec.ts – please confirm completeness.

Tests for processCssLayerNameExtraction live in
packages/clerk-js/src/utils/__tests__/appearance.spec.ts and cover many scenarios. Review that file to ensure it includes:

  • Handling of both theme and deprecated baseTheme
  • Array vs. single theme inputs
  • String vs. object theme types
  • CSS layer name extraction and prioritization (appearance-level vs. theme-level)
  • Edge cases such as undefined or other non-object inputs

@alexcarpenter
Copy link
Member Author

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @alexcarpenter - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.1.14-snapshot.v20250728160410
@clerk/astro 2.10.11-snapshot.v20250728160410
@clerk/backend 2.6.0-snapshot.v20250728160410
@clerk/chrome-extension 2.5.13-snapshot.v20250728160410
@clerk/clerk-js 5.77.0-snapshot.v20250728160410
@clerk/elements 0.23.46-snapshot.v20250728160410
@clerk/clerk-expo 2.14.12-snapshot.v20250728160410
@clerk/expo-passkeys 0.3.23-snapshot.v20250728160410
@clerk/express 1.7.13-snapshot.v20250728160410
@clerk/fastify 2.4.13-snapshot.v20250728160410
@clerk/localizations 3.20.4-snapshot.v20250728160410
@clerk/nextjs 6.27.0-snapshot.v20250728160410
@clerk/nuxt 1.7.14-snapshot.v20250728160410
@clerk/clerk-react 5.37.0-snapshot.v20250728160410
@clerk/react-router 1.8.7-snapshot.v20250728160410
@clerk/remix 4.10.7-snapshot.v20250728160410
@clerk/shared 3.15.1-snapshot.v20250728160410
@clerk/tanstack-react-start 0.21.3-snapshot.v20250728160410
@clerk/testing 1.10.7-snapshot.v20250728160410
@clerk/themes 2.4.2-snapshot.v20250728160410
@clerk/types 4.71.0-snapshot.v20250728160410
@clerk/vue 1.8.21-snapshot.v20250728160410

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.1.14-snapshot.v20250728160410 --save-exact

@clerk/astro

npm i @clerk/astro@2.10.11-snapshot.v20250728160410 --save-exact

@clerk/backend

npm i @clerk/backend@2.6.0-snapshot.v20250728160410 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@2.5.13-snapshot.v20250728160410 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@5.77.0-snapshot.v20250728160410 --save-exact

@clerk/elements

npm i @clerk/elements@0.23.46-snapshot.v20250728160410 --save-exact

@clerk/clerk-expo

npm i @clerk/clerk-expo@2.14.12-snapshot.v20250728160410 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@0.3.23-snapshot.v20250728160410 --save-exact

@clerk/express

npm i @clerk/express@1.7.13-snapshot.v20250728160410 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.4.13-snapshot.v20250728160410 --save-exact

@clerk/localizations

npm i @clerk/localizations@3.20.4-snapshot.v20250728160410 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@6.27.0-snapshot.v20250728160410 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@1.7.14-snapshot.v20250728160410 --save-exact

@clerk/clerk-react

npm i @clerk/clerk-react@5.37.0-snapshot.v20250728160410 --save-exact

@clerk/react-router

npm i @clerk/react-router@1.8.7-snapshot.v20250728160410 --save-exact

@clerk/remix

npm i @clerk/remix@4.10.7-snapshot.v20250728160410 --save-exact

@clerk/shared

npm i @clerk/shared@3.15.1-snapshot.v20250728160410 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@0.21.3-snapshot.v20250728160410 --save-exact

@clerk/testing

npm i @clerk/testing@1.10.7-snapshot.v20250728160410 --save-exact

@clerk/themes

npm i @clerk/themes@2.4.2-snapshot.v20250728160410 --save-exact

@clerk/types

npm i @clerk/types@4.71.0-snapshot.v20250728160410 --save-exact

@clerk/vue

npm i @clerk/vue@1.8.21-snapshot.v20250728160410 --save-exact

@alexcarpenter alexcarpenter merged commit d4d2612 into main Jul 29, 2025
36 checks passed
@alexcarpenter alexcarpenter deleted the alexcarpenter/base-theme-spike branch July 29, 2025 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants