Clerk Changelog

Changelog June 23, 2023


This week, we released Self Service Delete, Organization Creation Permissions, Enhanced Bot Protection, and various security and performance enhancements.

🗑️ Self Service Delete

We've introduced a new feature that allows users to easily delete their user accounts from your application. With the Self Service Delete feature, users can now delete their accounts directly through the <UserProfile /> component. This convenient functionality can be enabled through the Clerk Dashboard.

For our B2B customers, we've also extended this capability to administrators, who can now delete organizations directly through the <OrganizationProfile /> component. This provides enhanced control and management options for organizations within your application.

🔒 Permissions for Organization Creation

We have introduced a new feature that allows admins to have granular control over organization creation permissions for application users. With this feature, administrators can now decide whether users are allowed to create organizations. This provides you with extra control over the number of organizations within your Clerk application, ensuring that it aligns with your specific requirements and organizational structure. Note: You are still only billed on the number of active organizations in use, not the total number of organizations.

The organization creation permission setting is respected across all our stacks, including Clerk’s UI components, frontend API, and backend API.

🤖 Enhanced Bot Detection for Hosted Pages

We have introduced enhanced bot protection for our customers who are using Clerk’s Hosted Pages feature to help detect and mitigate bot attacks. In order to maintain the integrity of your application, all production instances now include additional measures against bot activity. If a suspicious bot attempts to access Hosted Pages, a “Verification Challenge” will be triggered.

This challenge serves as a verification process, similar to a CAPTCHA, to ensure that the user accessing the pages is human.

✨ Other Fixes & Improvements

  • Implemented PKCE (Proof Key for Code Exchange) support for Clerk's provided OAuth 2 IDP, improving security for user authentication and authorization code exchanges.
  • The experimental_allowed_origins parameter has been officially removed from the Clerk Backend API /v1/instance endpoint following its deprecation.
  • Improved Clerk Images with optimizations including:
    • Implementation of dynamic format negotiation that supports avif and webp formats and falls back to jpeg when needed, yielding a ~50% size reduction.
    • Images are now scaled down to a max width of 1920 and a default quality of 80 for improved performance.
  • Enhanced dashboard experience now offers a cleaner, unified interface for editing and viewing SAML connections.
  • The PATCH /me {password} endpoint in the dashboard is now deprecated and replaced with the more secure /v1/me/change_password endpoint. This new endpoint requires the inclusion of the old password, enhancing the security of password changes.
  • The Expo SDK now supports base64 image uploads for user profile images and organization logos.

📅 Events

Dive into AI applications at the Pinecone Hackathon, proudly sponsored by Clerk. This week-long event challenges you to devise solutions for real-world issues using Generative AI tools. The deadline for participation is Jun 26, 2023, at 12:00am EDT.

Join the hackathon here

📚 Resources

  • AI Getting Started Stack: Martin from a16z open sourced a Javascript AI “getting started” stack to allow devs to quickly spin up AI projects. Read all about it in this post.
  • We’ve got two editions of How We Roll for you this week, which covers how Clerk implements authentication, both from Clerk’s own James Perkins.
    • Customization: The 5th chapter of "How We Roll" covers the various ways developers can customize Clerk's UI components.
    • User Profile: The 6th chapter of “How We Roll” covers how Clerk’s <UserProfile /> component allows users to control their data.

🙌 Community Shoutouts

  • Shoutout to Timothy Miller for open sourcing create-t4-app, a Type-Safe, Full-Stack Starter Kit for React Native + Web, offering easy integration to Cloudflare services and built-in support for Clerk.
  • Congratulations to our Clerk Community member bradw for launching Sociafy, an alternative to Sociafy lets you curate elegant pages that reflect your individuality, and utilizes Clerk for user authentication.
  • A round of applause for Clerk Community member Zach for the launch of Artisan, a web application that leverages the power of Clerk and T3 Turbo. Artisan, an AI-driven coach, is here to help you achieve your self-guided learning goals with greater consistency.

Stay tuned for future updates. If you have feedback or suggestions, leave us feedback on the docs via Docsly, tweet us at @ClerkDev, or join the Clerk Community on Discord.

Nick Parsons

Changelog June 9, 2023


This week, we shipped a public beta for SAML and several updates and improvements to localization, multidomain support, password imports, and more.

SAML is Now in Public Beta

We're excited to announce that Clerk now supports SAML-based Enterprise Single Sign-On (SSO). As of now, the SAML feature is in public beta, with general availability expected later this summer. Clerk’s new SAML SSO feature was carefully built to improve the secure authentication experience for both you and your customers:

Integrate with Top Identity Providers

Clerk's new SAML-based Enterprise SSO feature allows you to seamlessly integrate with top identity providers such as Okta, Azure AD, and Google. The integration process is straightforward, and our docs provide an in-depth glossary for correctly mapping IdP claims to Clerk fields.

Secure, User-friendly Authentication Experience

When SAML is configured, your users enter their email address on your sign in page and, if the email matches an active SAML connection, they will be redirected to the configured IdP for a secure login using their credentials. Best of all, this seamless authentication experience works out of the box with Clerk's UI components.

Public Beta & Configuration

While in public beta, SAML is available at no cost for all customers subscribed to a Business plan. However, once SAML transitions to general availability, the pricing structure will change, with SAML being billed at $50 per connection per month.

To get started, go to your dashboard and navigate to User & Authentication > Enterprise Connections. From there, click on "Create Connection" to begin the setup process.

For detailed instructions on configuration and mapping IdP fields to Clerk, please see the docs.

Other Fixes & Improvements

  • Thanks to community contributions, we now have localization support for additional languages:
  • Satellite domains can now be removed using the Clerk Backend API.
  • Multidomain support has been extended to Node/Express applications.
  • Users will now be notified via email when modifications are made to their primary email address.
  • We've extended user imports to include support for Django's bcrypt SHA256 password hasher.
  • New contribution guide for open source contributors who want to open pull requests to our open source Javascript SDKs.
  • For greater interoperability across various build tools and frameworks, we now facilitate both ESM and CJS builds in @clerk/clerk-react.
  • Added support to @clerk/nextjs for Next.js apps deployed to AWS Amplify and Railway.


Community Shoutouts

  • A big thank you to Petr Doležal, Ahmet Polat, Ilya Nikishin, and Cali Castle for your help adding additional localization support to Clerk.
  • Shoutout to Pranav for the launch of Swiftube, a React app that uses Clerk (for authentication) and transforms user prompts into animated videos. Learn how it was built in this post.
  • Kudos to the team at Tunnel, who just launched this week using Clerk, for making it easier for developers to tunnel their applications locally.
  • Congratulations to the folks at Maple, who also launched with Clerk this week, for introducing a new platform for privacy-focused analytics.

Stay tuned for future updates. If you have feedback or suggestions, leave us feedback on the docs via Docsly, tweet us at @ClerkDev, or join the Clerk Community on Discord.

Nick Parsons

Changelog May 26, 2023


This week, we launched a major upgrade to avatars, enabled domain updates in the dashboard, improved backend sorting capabilities, password features, and more.

Clerk Avatars


Clerk improved the default avatars for users who haven't uploaded a profile image by adding customization options. These unique avatars are designed to add an extra level of polish to your application and can be fully customized to align with your brand.


Avatars can easily be customized via the dashboard under Customization > Avatars. In there, you can adjust the following settings:

  • Background: Select from an array of color options and effects. You can retain the default marble effect, which accommodates up to five colors, or opt for a solid background.
  • Foreground: Choose from a diverse range of colors and styles. Your options encompass initials, silhouette, or none at all.

An Eye-Catching Shimmer

To add a unique touch, we've implemented a subtle shimmer animation on our internal avatar component. This is available on the <UserButton /> component and you can enable the shimmer effect using the appearance prop:

    layout: {
      shimmer: true,

Learn more in this blog post

Other Fixes & Improvements

  • Change domains and subdomains for production instances via the Dashboard. (Link to Docs)
  • Added sorting capabilities Clerk Backend API organization membership and user list endpoints. (Org Membership, User)
  • Implemented allowedOrigins prop to mitigate the risk of open redirect vulnerabilities.
  • Added new I18n translations for Clerk JS, including Japanese [PR] and Hebrew [PR], thanks to community contributions.
  • Introduced a feature to delete satellite domains in the multi-domain configuration. (Link to Docs)
  • Enhanced password reset flow for strong password verification, adjustable complexity settings, and guidance cues. (Read More)

Upcoming Events

RenderATL – May 31st to June 2nd

Several team members are heading down to Atlanta to participate in RenderATL. If you are attending, we would love to meet you! Keep an eye out for our team who will be handing out warm cookies and invitations to community-driven side events.

CityJS – May 29th to May 31st

Our engineering team is heading to CityJS in Athens with swag. Be sure to tune in for a talk from our VP of Engineering, Sokratis Vidros, on how to add authentication to your Next.js app in just 7 minutes.

Community Shoutouts

  • A big thank you to Raz Levi and Daichi Ninomiya for their pull request adding localization support for Hebrew and Japanese
  • Another big thanks to Tom Milewski for reducing our SVG size by 80% in our ClerkJS package, allowing us to reduce our bundle size even more.
  • A thanks to DevelopedByEd for featuring us in his “My Ultimate tech stack 2023” video, check it out on YouTube.


Stay tuned for future updates. If you have feedback or suggestions, leave us feedback on the docs (thank you Docsly), tweet us at @ClerkDev, or join the Clerk Community on Discord.

Nick Parsons

Changelog April 21, 2023


A new change password flow, bulk invites for organizations, hosted pages in the dashboard!

Change password flow

We introduced a new Change password flow this week, that allows the user to change their password and log out all sessions via our user profile component.

Bulk Organization invitations

You can now bulk invite users to an organization via Clerk's API allowing you to invite a whole team quickly.

You can specify a different role for each invited organization member. New organization invitations get a "pending" status until they are revoked by an organization administrator or accepted by the invitee.

The request body supports passing an optional redirect_url parameter for each invitation. When the invited user clicks the link to accept the invitation, they will be redirected to the provided URL.

Use this parameter to implement a custom invitation acceptance flow. You must specify the ID of the user that will send the invitation with the inviter_user_id parameter.

Each invitation can have a different inviter user. Inviter users must be members with administrator privileges in the organization. Only "admin" members can create organization invitations.

Below is a simplified version

curl -XPOST -H "Content-type: application/json" -d '[
    "email_address": "string",
    "inviter_user_id": "string",
    "role": "admin",
    "public_metadata": {},
    "private_metadata": {},
    "redirect_url": "string"
]' '{organization_id}/invitations/bulk'

Check out our backend API reference for more details:

Hosted Pages

We have added a dedicated section for our hosted pages in the Clerk dashboard. You can find them under customization, this will give you links to preview hosted pages as well as a way to customize some of the look and feel.

Community shoutouts

This week I'd like to highlight a few community creators who created some informative videos on using Clerk!

First up we have Hamed Bahram who created a video on protecting your e-commerce website using Clerk, this 30 minute tutorial shows the power of Clerk from client to server.

Secondly Elias Wambugu who's channel is know as The Source Code gives you a introduction into Clerk with React in just 10 minutes!

James Perkins

Changelog April 7, 2023


Expo 48 support, Improving our components, Runtime keys for Next.js...

This week, the team has been improving the DX of Clerk and introducing some important features.

Expo 48 Support

Clerk now has full support for Expo 48 with this change we introduced a brand new hook called useOAuth this hook dramatically improves the developer experience. Here are two examples of the code to handle Discord OAuth, both handle account transfers.


import { useSignUp, useSignIn } from '@clerk/clerk-expo'
import React from 'react'
import { Button, View } from 'react-native'

import * as AuthSession from 'expo-auth-session'

const SignInWithOAuth = () => {
  const { isLoaded, signIn, setSession } = useSignIn()
  const { signUp } = useSignUp()
  if (!isLoaded) return null

  const handleSignInWithDiscordPress = async () => {
    try {
      const redirectUrl = AuthSession.makeRedirectUri({
        path: '/oauth-native-callback',

      await signIn.create({
        strategy: 'oauth_discord',

      const {
        firstFactorVerification: { externalVerificationRedirectURL },
      } = signIn

      if (!externalVerificationRedirectURL) throw 'Something went wrong during the OAuth flow. Try again.'

      const authResult = await AuthSession.startAsync({
        authUrl: externalVerificationRedirectURL.toString(),
        returnUrl: redirectUrl,

      if (authResult.type !== 'success') {
        throw 'Something went wrong during the OAuth flow. Try again.'

      // Get the rotatingTokenNonce from the redirect URL parameters
      const { rotating_token_nonce: rotatingTokenNonce } = authResult.params

      await signIn.reload({ rotatingTokenNonce })

      const { createdSessionId } = signIn

      if (createdSessionId) {
        // If we have a createdSessionId, then auth was successful
        await setSession(createdSessionId)
      } else {
        // If we have no createdSessionId, then this is a first time sign-in, so
        // we should process this as a signUp instead
        // Throw if we're not in the right state for creating a new user
        if (!signUp || signIn.firstFactorVerification.status !== 'transferable') {
          throw 'Something went wrong during the Sign up OAuth flow. Please ensure that all sign up requirements are met.'

        console.log("Didn't have an account transferring, following through with new account sign up")

        // Create user
        await signUp.create({ transfer: true })
        await signUp.reload({
          rotatingTokenNonce: authResult.params.rotating_token_nonce,
        await setSession(signUp.createdSessionId)
    } catch (err) {
      console.log(JSON.stringify(err, null, 2))
      console.log('error signing in', err)

  return (
    <View className="rounded-lg border-2 border-gray-500 p-4">
      <Button title="Sign in with Discord" onPress={handleSignInWithDiscordPress} />

export default SignInWithOAuth


import { useOAuth } from '@clerk/clerk-expo'
import React from 'react'
import { Button, View } from 'react-native'
import { useWarmUpBrowser } from '../hooks/useWarmUpBrowser'

const SignInWithOAuth = () => {

  const { startOAuthFlow } = useOAuth({ strategy: 'oauth_discord' })

  const handleSignInWithDiscordPress = React.useCallback(async () => {
    try {
      const { createdSessionId, signIn, signUp, setActive } = await startOAuthFlow()
      if (createdSessionId) {
        setActive({ session: createdSessionId })
      } else {
        // Modify this code to use signIn or signUp to set this missing requirements you set in your dashboard.
        throw new Error('There are unmet requirements, modifiy this else to handle them')
    } catch (err) {
      console.log(JSON.stringify(err, null, 2))
      console.log('error signing in', err)
  }, [])

  return (
    <View className="rounded-lg border-2 border-gray-500 p-4">
      <Button title="Sign in with Discord" onPress={handleSignInWithDiscordPress} />

export default SignInWithOAuth

At this point we believe that our authentication offering is better than Expo's direct offer! If you are ready to get started with Expo and Clerk, check out our documentation

Improving our components

Many of our users offer email,username and phone as a way for their users to authenticate. In the past we would have a single input for all of the options and the user would have to type in their phone number including the country code which made it difficult

We now offer a way to switch the input allow the user to see a familiar phone input.

@clerk/nextjs runtime key support

We can now support keys at runtime for users who may have multiple projects under a single monorepo or want fine grain usage of keys.

export default withClerkMiddleware((request: NextRequest) => {
  // pass the secret key to getAuth
  const { userId } = getAuth(req,{
     secretKey: "CLERK_SECRET_KEY"

  if (!userId) {
    // redirect the users to /pages/sign-in/[[...index]].ts

    const signInUrl = new URL("/sign-in", request.url);
    signInUrl.searchParams.set("redirect_url", request.url);
    return NextResponse.redirect(signInUrl);
  // pass the keys to Middleware
  secretKey: "CLERK_SECRET_KEY",

Create your organization with a slug

The <CreateOrganization/> component now exposes the slug field for you to input the slug you want when an organization is created. It is still optional and by default will use the name of the organization.

Dutch language support

We now have support for localization in Dutch thanks to a Clerk user who translated our components.

import { ClerkProvider } from "@clerk/nextjs";
import { nlNL } from "@clerk/localizations";
import type { AppProps } from "next/app";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ClerkProvider localization={nlNL} {...pageProps}>
      <Component {...pageProps} />

export default MyApp;
James Perkins

Changelog March 31, 2023


Improved Web Vitals, Official Chrome Extension Support, OIDC Provider beta, Cross-Origin Embedder Policy Support

Improved Web Vitals

This week we rolled out major changes to how Clerk's Javascript bundle is split and downloaded. Chances are you didn't notice anything, but your production application should be seeing ~10 points higher performance on than last week.

Official Chrome Extension Support

Use Clerk and React to building a Chrome extension. We've launched @clerk/chrome-extension on NPM, and a starter repository on GitHub to help kick off your next extension project.

OIDC Provider (beta)

With Clerk, your application can now serve as an Open ID Connect (OIDC) provider. Please reach out through Discord if you'd like to join the beta.

OIDC is a subset of OAuth2. In the future, Clerk will also enable your application to serve as a OAuth2 provider, including supporting grant flows with custom scopes.

Cross-Origin Embedder Policy Support for Profile Images

Clerk profile images are now served with the Access-Control-Allow-Origin: * header to enable embeds in applications with cross-origin embedder policies.

Colin Sidoti