npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@resonant-projects/clerk-solidjs

v4.3.2

Published

Clerk SDK for SolidJS and SolidStart

Readme


This is an unofficial community-led port of the Clerk React SDK for SolidJS and SolidStart.

Maintained by Resonant Projects as a hard fork of clerk-solidjs by Ian Pascoe, which is no longer published.

Clerk documentation

Released on NPM

NPM version NPM Downloads

Maintained on GitHub

GitHub stars GitHub watchers GitHub license GitHub forks GitHub issues GitHub pull requests GitHub contributors GitHub last commit

pnpm turborepo


Overview

Clerk is the easiest way to add authentication and user management to your application. Add sign up, sign in, and profile management to your application in minutes.

Features

This project tracks Clerk Core 3 and @clerk/react:
✔ SSR support
✔ Components, with the prebuilt UI loaded from @clerk/ui
✔ Custom menu items in <UserButton />
✔ Custom pages in <UserProfile />, <UserButton />, <OrganizationProfile /> and <OrganizationSwitcher />
✔ Hooks*

Plus additional features for SolidStart:
✔ Middleware
✔ Server-side auth() helper

* = Hooks with parameters have been altered to use the Accessor<Params> type for reactivity. For example:

useOrganizationList(() => ({ userMemberships: { infinite: true } }));

Getting Started

Prerequisites

  • SolidJS ^1.9
  • SolidStart ^2 and @solidjs/router >=0.16 <2, for the /start entries (optional otherwise)
  • Node.js >=22.12
  • An ES module build: 4.0 ships ESM only

Upgrading from 3.x? See MIGRATION.md.

Installation

npm install @resonant-projects/clerk-solidjs
# or
yarn add @resonant-projects/clerk-solidjs
# or
pnpm add @resonant-projects/clerk-solidjs
# or
bun add @resonant-projects/clerk-solidjs

Build

pnpm run build

To build the package in watch mode, run the following:

pnpm run dev

Testing

Run the unit and package checks from the repository root:

pnpm run test
pnpm run lint
pnpm run type-check
pnpm --filter @resonant-projects/clerk-solidjs run publint
pnpm --filter @resonant-projects/clerk-solidjs run attw

The Playwright suite targets examples/basic against a real Clerk development instance. Set VITE_CLERK_PUBLISHABLE_KEY (or CLERK_PUBLISHABLE_KEY) and CLERK_SECRET_KEY, then build the example and run:

pnpm run build
pnpm run e2e

In GitHub Actions, the E2E workflow reads the publishable key from VITE_CLERK_PUBLISHABLE_KEY as either a secret or a repository variable, and maps it to both env names that the example and tests accept.

It runs against both example apps: examples/basic (SolidStart, where it also checks the middleware, auth() and API routes) and examples/solid-vite (a client-only app on Vite and @solidjs/router). E2E_APPS=basic pnpm run e2e runs only the SolidStart app. The organization spec needs Organizations turned on in the instance, and the billing spec needs billing for users with a public plan; each is skipped, and says why, when its feature is off. CI also runs the SolidStart app on the oldest SolidStart and @solidjs/router the peer ranges allow, and a weekly workflow runs everything on the newest @clerk/* packages.

Usage

Clerk requires your application to be wrapped in the <ClerkProvider /> context.

Set VITE_CLERK_PUBLISHABLE_KEY to your Publishable key in your .env.local file. ClerkProvider reads it, or CLERK_PUBLISHABLE_KEY, when you don't pass the publishableKey prop. A missing or malformed key fails the render, on the server too.

// App.tsx

import { Router } from '@solidjs/router';
import { FileRoutes } from '@solidjs/start/router';
import { Suspense } from 'solid-js/web';
import { ClerkProvider } from '@resonant-projects/clerk-solidjs';

import './app.css';

export default function App() {
  return (
    <Router
      root={(props) => (
        <ClerkProvider
          publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}
        >
          <Suspense>{props.children}</Suspense>
        </ClerkProvider>
      )}
    >
      <FileRoutes />
    </Router>
  );
}

Once you have wrapped your app in <ClerkProvider /> you can access hooks and components.

import {
  ClerkFailed,
  ClerkLoading,
  Show,
  SignInButton,
  UserButton,
  useAuth
} from '@resonant-projects/clerk-solidjs';

export default function MyComponent() {
  const { userId } = useAuth();

  return (
    <div>
      <ClerkLoading>
        <p>Loading...</p>
      </ClerkLoading>
      <ClerkFailed>
        <p>Sign-in is unavailable right now.</p>
      </ClerkFailed>
      <Show when="signed-in" fallback={<SignInButton />}>
        <UserButton fallback={<span>Loading account...</span>} />
        <p>Welcome, {userId()}</p>
      </Show>
    </div>
  );
}

<Show>

<Show> is Clerk Core 3's replacement for SignedIn, SignedOut and Protect. when takes 'signed-in', 'signed-out', an authorization check such as { role: 'org:admin' }, { permission: 'org:billing:manage' }, { feature: 'premium' } or { plan: 'pro' }, or a function that receives has. It renders nothing until auth has loaded, renders fallback when when does not hold, and only creates its children once they are authorized, so their effects and fetches never run for the wrong user.

It shares its name with solid-js's Show. In a file that uses both, import Clerk's as ClerkShow:

import { Show } from 'solid-js';
import { ClerkShow } from '@resonant-projects/clerk-solidjs';

<ClerkShow when={{ role: 'org:admin' }} fallback={<p>Admins only</p>}>
  <Show when={settings()}>{(s) => <AdminPanel settings={s()} />}</Show>
</ClerkShow>;

4.0 removed SignedIn, SignedOut and Protect; see MIGRATION.md.

Loading state

ClerkLoading shows while Clerk loads, including in the server render. ClerkLoaded shows once Clerk is ready, ClerkFailed if clerk-js failed to load (a blocked script, for example), and ClerkDegraded if it loaded but part of it is not working. useAuth().getToken() and signOut() wait until Clerk is ready; on the server, getToken() throws clerk_runtime_not_browser.

Buttons and components

SignInButton, SignUpButton, SignOutButton and SignInWithMetamaskButton render on the server and before Clerk loads; a click before then runs once Clerk is ready. Pass text, or your own element, as the only child. Your element gets the click handler instead of being wrapped in another button:

<SignInButton mode="modal" initialValues={{ emailAddress: email() }}>
  <button class="btn-primary">Log in</button>
</SignInButton>

SignOutButton without redirectUrl goes to your afterSignOutUrl; @clerk/react's goes to /.

SignIn, UserButton and the other Clerk components render their element on the server too, and take a fallback that shows until Clerk has rendered.

Appearance

appearance is typed with Clerk Core 3's theme on ClerkProvider and every component: theme, options, variables, elements and captcha. The Core 2 baseTheme and layout keys are type errors. With a bundled ui from @clerk/ui, appearance follows that version's types.

For redirects after sign-in and sign-up, use signInFallbackRedirectUrl, signUpFallbackRedirectUrl and their Force variants. 4.0 removed the Core 2 afterSignInUrl and afterSignUpUrl.

Signed-in state and authorization

useAuth() follows Clerk Core 3. A session that still has tasks to finish, such as choosing an organization or setting up MFA, counts as signed out. Pass treatPendingAsSignedOut: false to useAuth or <Show> to treat it as signed in instead. <TaskChooseOrganization>, <TaskResetPassword> and <TaskSetupMFA> let the user finish those tasks, and <RedirectToTasks> or useClerk()().redirectToTasks() sends them to Clerk's task pages. useSession().isSignedIn() is false for such a session, while session() still returns it, as in @clerk/react.

has() checks roles, permissions, features, plans and reverification together, and returns false for anything it cannot confirm. Call it inside JSX or a memo to keep it reactive.

const { isSignedIn, has } = useAuth();
const canManageMembers = () =>
  has({ permission: 'org:sys_memberships:manage' });
const isPro = () => has({ plan: 'pro' });

Custom sign-in and sign-up flows

useSignIn(), useSignUp() and useWaitlist() are Clerk Core 3's signal-based hooks, as in @clerk/react 6. Each returns the resource, errors and fetchStatus, kept current from clerk-js. Their methods wait for Clerk to load, so a form can call them right away. On the server they return defaults.

The resource and errors stay reactive when destructured. fetchStatus is a string, so read it from the result:

import { useNavigate } from '@solidjs/router';
import { useSignIn } from '@resonant-projects/clerk-solidjs';
import { createSignal, Show } from 'solid-js';

export default function SignInForm() {
  const state = useSignIn();
  const { signIn, errors } = state;
  const navigate = useNavigate();
  const [identifier, setIdentifier] = createSignal('');
  const [password, setPassword] = createSignal('');

  const submit = async (event: SubmitEvent) => {
    event.preventDefault();
    await signIn.password({ identifier: identifier(), password: password() });
    if (signIn.status === 'complete') {
      await signIn.finalize({ navigate: () => navigate('/') });
    }
  };

  return (
    <form onSubmit={submit}>
      <input onInput={(e) => setIdentifier(e.currentTarget.value)} />
      <Show when={errors.fields.identifier}>{(e) => <p>{e().message}</p>}</Show>
      <input
        type="password"
        onInput={(e) => setPassword(e.currentTarget.value)}
      />
      <button disabled={state.fetchStatus === 'fetching'}>Sign in</button>
    </form>
  );
}

The Core 2 hooks, with isLoaded, the client's signIn or signUp and setActive, are in @resonant-projects/clerk-solidjs/legacy, like @clerk/react/legacy.

SSO callbacks

Render <HandleSSOCallback> on the route an OAuth or enterprise SSO provider redirects back to, such as src/routes/sso-callback.tsx. It finishes the sign-in or sign-up with the Core 3 resources: it resolves a pending bot-protection check, then finalizes, transfers between sign-in and sign-up, or calls navigateToSignIn or navigateToSignUp when another step is needed.

import { useNavigate } from '@solidjs/router';
import { HandleSSOCallback } from '@resonant-projects/clerk-solidjs';

export default function SSOCallback() {
  const navigate = useNavigate();
  return (
    <HandleSSOCallback
      navigateToApp={({ decorateUrl }) => {
        // For Safari's cookie cap, decorateUrl can return a Clerk URL.
        const url = decorateUrl('/');
        if (url.startsWith('http')) window.location.href = url;
        else navigate(url);
      }}
      navigateToSignIn={() => navigate('/sign-in')}
      navigateToSignUp={() => navigate('/sign-up')}
    />
  );
}

Reverification

useReverification(fetcher) wraps a call that may need the user to verify again, such as one to a server function that returns reverificationError(). It opens Clerk's reverification modal, then runs the call again once the user has verified. Pass onNeedsReverification to show your own prompt instead.

const { user } = useUser();
const setPrimaryEmail = useReverification((emailAddressId: string) =>
  user()!.update({ primaryEmailAddressId: emailAddressId })
);

More components and hooks

As in @clerk/react:

  • <PricingTable> shows your plans; its fallback stays until Clerk has fetched them.
  • <APIKeys> manages API keys, and useAPIKeys() pages through them: useAPIKeys(() => ({ subject: organization()?.id })).
  • <UserAvatar> is the signed-in user's avatar.
  • <OAuthConsent> and useOAuthConsent() cover an OAuth application's consent screen. <OAuthDeviceVerification> and useOAuthDeviceVerification() cover the device flow: lookup, then approve or deny.
  • <InviteMembersButton> opens the invite-members modal.
  • useOrganizationCreationDefaults() suggests a new organization's name and slug, when the instance has that turned on.
  • getToken() returns the session token outside any component.

Hook params that can change are accessors, and results are accessors, as in the other hooks. On a development instance without organizations, useOrganization() and useOrganizationList() with list params trigger Clerk's prompt to turn them on.

Wrap part of the app in <UNSAFE_PortalProvider getContainer={() => el}> to render Clerk's components, popovers and modals inside el, such as a dialog, instead of document.body.

Billing (experimental)

Billing is experimental in @clerk/react too, so it has its own entry, and its API can change in a minor release:

import { Show } from '@resonant-projects/clerk-solidjs';
import {
  CheckoutButton,
  usePlans
} from '@resonant-projects/clerk-solidjs/experimental';
import { For } from 'solid-js';

const Plans = () => {
  const plans = usePlans(() => ({ for: 'user' }));
  return (
    <Show when="signed-in">
      <For each={plans.data()}>
        {(plan) => (
          <CheckoutButton planId={plan.id} planPeriod="month">
            {`Choose ${plan.name}`}
          </CheckoutButton>
        )}
      </For>
    </Show>
  );
};
  • <CheckoutButton>, <PlanDetailsButton> and <SubscriptionDetailsButton> open Clerk's billing drawers.
  • usePlans(), useStatements(), usePaymentAttempts() and usePaymentMethods() page through billing data, as useAPIKeys() does. useSubscription() returns the current subscription.
  • useCheckout(() => ({ planId, planPeriod })) drives a custom checkout: checkout.start(), confirm() and finalize(). <CheckoutProvider> can supply its options instead.
  • <PaymentElementProvider>, <PaymentElement> and usePaymentElement() render Stripe's payment form and submit it. Clerk loads Stripe.js itself.

Render the buttons and useCheckout() for a signed-in user, and with for="organization" only with an active organization. Otherwise they throw to the nearest ErrorBoundary. The hooks wait until billing is on for the payer.

Custom menu items and pages

The components take the same children as @clerk/react. Icons and page bodies render through Solid's <Portal> from inside the Clerk component, so your app's context (router, theme, data clients) is available in them.

import { UserButton } from '@resonant-projects/clerk-solidjs';

<UserButton userProfileMode="modal">
  <UserButton.MenuItems>
    <UserButton.Action
      label="Notifications"
      labelIcon={<BellIcon />}
      open="notifications"
    />
    <UserButton.Link label="Docs" labelIcon={<BookIcon />} href="/docs" />
    <UserButton.Action label="manageAccount" />
    <UserButton.Action label="signOut" />
  </UserButton.MenuItems>
  <UserButton.UserProfilePage
    label="Notifications"
    url="notifications"
    labelIcon={<BellIcon />}
  >
    <NotificationSettings />
  </UserButton.UserProfilePage>
  <UserButton.UserProfilePage label="account" />
</UserButton>;
  • UserButton.Action with open opens that profile page in the modal; with onClick it runs your handler. A bare label of manageAccount or signOut reorders Clerk's own items.
  • UserProfile.Page / UserProfile.Link, OrganizationProfile.Page / OrganizationProfile.Link and OrganizationSwitcher.OrganizationProfilePage / .OrganizationProfileLink work the same way. A bare label (account, security, billing, apiKeys, or general, members for organizations) reorders Clerk's own pages.

To open the profile modal on one of your pages from app code (for example from an old URL), mount <UserProfileModal> with the same page children. It opens Clerk's modal while mounted and closes it on unmount:

<Show when={openAt()} keyed>
  {(path) => (
    <UserProfileModal __experimental_startPath={path}>
      <AccountPages />
    </UserProfileModal>
  )}
</Show>

Rendering a button somewhere else

<UserButton __experimental_asProvider> and <OrganizationSwitcher __experimental_asProvider> render their children instead of themselves, and the component renders where its __experimental_Outlet is, with the provider's props, custom pages and menu items. The Outlet can add props of its own:

<UserButton __experimental_asProvider showName>
  <UserButton.UserProfilePage
    label="Settings"
    url="settings"
    labelIcon={<GearIcon />}
  >
    <Settings />
  </UserButton.UserProfilePage>
  <header class="toolbar">
    <UserButton.__experimental_Outlet />
  </header>
</UserButton>

These are experimental in @clerk/react too.

Email links

useEmailLink(() => signIn) returns startEmailLinkFlow(params) and cancelEmailLinkFlow(), as @clerk/react does. The flow is cancelled when the component unmounts, or when the accessor returns another resource. Before 4.3 they were accessors, called as startEmailLinkFlow()(params). That still works, with a deprecation warning.

Clerk UI script

Clerk Core 3 loads the prebuilt components from @clerk/ui. The provider loads it from Clerk's CDN after clerk-js. To bundle it instead, pass ui from @clerk/ui; to skip it (for example when you only use hooks and control components), pass prefetchUI={false}. With the SolidStart provider, CLERK_JS_URL, CLERK_JS_VERSION, CLERK_UI_URL, CLERK_UI_VERSION and CLERK_PREFETCH_UI=false configure the scripts.

Middleware

clerkMiddleware() authenticates every request on the server. Register it in your SolidStart middleware with createMiddleware, and point your config at the file with solidStart({ middleware: './src/middleware.ts' }):

// src/middleware.ts
import { createMiddleware } from '@solidjs/start/middleware';
import { clerkMiddleware } from '@resonant-projects/clerk-solidjs/start/server';

export default createMiddleware([clerkMiddleware()]);

It reads CLERK_SECRET_KEY, VITE_CLERK_PUBLISHABLE_KEY (or CLERK_PUBLISHABLE_KEY) and the other CLERK_* variables on each request. Pass options to override them. Every authenticateRequest() option is accepted, such as authorizedParties, organizationSyncOptions, satelliteAutoSync and jwtKey. When options depend on the request, for example per-tenant keys or runtime bindings, pass a function. It receives the request's url and the SolidStart event:

export default createMiddleware([
  clerkMiddleware(async ({ url }) => ({
    secretKey: await secretKeyForTenant(url.hostname)
  }))
]);

The middleware puts Clerk's response headers on every response, including session-refresh cookies and x-clerk-auth-* diagnostics, and hands the request's auth state to the browser so the first render matches the server. The older createMiddleware({ onRequest: [clerkMiddleware()] }) form still works.

Frontend API proxy

Where a network blocks Clerk's Frontend API, serve it from your app:

clerkMiddleware({ frontendApiProxy: { enabled: true } });

Requests under /__clerk (set another with path) go to Clerk without being authenticated, and the browser uses the proxy: unless you pass a proxyUrl, the proxy's URL becomes it. enabled can be a function of the request URL, such as (url) => url.hostname.endsWith('.example.com').

Content Security Policy

contentSecurityPolicy sets a Content-Security-Policy header that allows Clerk, the instance's Frontend API, Stripe and Cloudflare Turnstile. Your directives are merged with Clerk's, and ['none'] replaces a directive. reportOnly and reportTo report violations instead of, or as well as, blocking them.

With strict: true, scripts need a nonce, which is new for each request and is in event.locals.clerkNonce. Hand it to SolidStart, which adds it to its own scripts and to the one with Clerk's state:

// src/middleware.ts
export default createMiddleware([
  clerkMiddleware({ contentSecurityPolicy: { strict: true } })
]);

// src/entry-server.tsx
export default createHandler(
  () => <StartServer document={/* … */} />,
  (event) => ({ nonce: event.locals.clerkNonce })
);

'strict-dynamic' then lets those scripts load clerk-js and Clerk's UI.

Clerk's policy replaces one your route sets. A Reporting-Endpoints header your route sets keeps its other groups. In the deprecated createMiddleware({ onRequest }) form, Clerk's middleware runs before the route and cannot see what the route sets afterwards, so a policy the route sets replaces Clerk's. Use the array form above.

Debugging

debug: true logs, for each request, the options, the URL, the request state and the auth object, between [clerk debug start] and [clerk debug end] lines. It leaves credentials out. Keys and tokens are cut to their first characters and cookies to their names. URLs keep their parameter names but no values. Headers keep their values only when they carry no credentials, such as host, accept or x-clerk-auth-status; others are listed by name. Options and the auth object's debug data keep booleans, numbers and Clerk's own settings, such as domain; other text values are cut. The policy Clerk generates is logged as sent, since every browser receives it.

Server-only code

@resonant-projects/clerk-solidjs/start/server is server-only. In a browser build it resolves to a stand-in with the same exports. A route file can import auth for its "use server" functions without bundling @clerk/backend into the browser. Calling auth(), clerkClient() or the others in the browser throws an error that says where to call them.

On Netlify, handshake redirects on a development instance carry a cache-busting parameter, so Netlify does not serve one from its cache in a loop.

The auth() helper

With the middleware in place, auth() returns the request's auth object on the server: in "use server" functions and queries, API routes, and middleware that runs after clerkMiddleware(). event.locals.auth holds the same session object. To type it, add this line to a .d.ts file in your app, such as src/global.d.ts:

/// <reference types="@resonant-projects/clerk-solidjs/start/env" />

Leave it out if your app already declares auth on App.RequestEventLocals.

import { createAsync, query } from '@solidjs/router';
import {
  auth,
  clerkClient
} from '@resonant-projects/clerk-solidjs/start/server';

const getProfile = query(async () => {
  'use server';
  const { userId, redirectToSignIn } = auth();
  // A 307 to sign-in that comes back to this page afterwards.
  if (!userId) throw redirectToSignIn();
  return clerkClient().users.getUser(userId);
}, 'profile');

export default function Profile() {
  const user = createAsync(() => getProfile());
  // ...
}

A session with pending tasks counts as signed out unless you pass auth({ treatPendingAsSignedOut: false }). API routes can also accept machine tokens: API keys, M2M tokens and OAuth access tokens. Set CLERK_MACHINE_SECRET_KEY for M2M tokens.

// src/routes/api/data.ts
import { auth } from '@resonant-projects/clerk-solidjs/start/server';

export function GET() {
  const { isAuthenticated, tokenType } = auth({
    acceptsToken: ['session_token', 'api_key']
  });
  if (!isAuthenticated) return new Response(null, { status: 401 });
  // ...
}

clerkClient() is a Backend API client configured from the same env. verifyToken, createClerkClient, reverificationError and reverificationErrorResponse are exported from /start/server too.

Webhooks

// src/routes/api/webhooks.ts
import type { APIEvent } from '@solidjs/start/server';
import { verifyWebhook } from '@resonant-projects/clerk-solidjs/webhooks';

export async function POST({ request }: APIEvent) {
  try {
    const event = await verifyWebhook(request); // uses CLERK_WEBHOOK_SIGNING_SECRET
    // event.type, event.data
    return new Response(null, { status: 204 });
  } catch {
    return new Response('Invalid webhook signature', { status: 400 });
  }
}

Routing

@resonant-projects/clerk-solidjs/start exports SignIn, SignUp, UserProfile, OrganizationProfile and OrganizationList with path routing taken from the current route. Put them on a catch-all route, such as src/routes/sign-in/[...rest].tsx, and they need no path prop. The SolidStart ClerkProvider also makes Clerk's navigation wait until the router has finished each navigation.

For framework authors

@resonant-projects/clerk-solidjs/internal has what @clerk/react/internal offers frameworks built on it. Its API can change in a minor release:

  • MultisessionAppSupport renders its children again, from scratch, when the active session changes.
  • useDerivedAuth(() => authObject) gives useAuth's state for an auth object you have.
  • useRoutingProps(name, props, routingOptions) applies Clerk's routing defaults and checks.
  • publishableKeyFromHost and setErrorThrowerOptions.

For a runtime without a browser window, such as a browser extension's service worker, pass your own Clerk instance or constructor with experimental={{ runtimeEnvironment: 'headless' }}. The provider then loads it without fetching scripts or Clerk's UI, and without setting window globals.

One ClerkProvider per tree: a provider inside another throws. Separate roots, such as islands, each get their own.

Examples

Basic

Basic example: SolidStart, with server rendering, clerkMiddleware and auth().

Vite

Vite example: a client-only Solid app on Vite and @solidjs/router.

Support

You can get in touch in any of the following ways:

Contributing

We're open to all community contributions! If you'd like to contribute in any way, please read our contribution guidelines.

Security

clerk-solidjs follows good practices of security, but 100% security cannot be assured.

clerk-solidjs is provided "as is" without any warranty. Use at your own risk.

For more information and to report security issues, please refer to our security documentation.

License

This project is licensed under the MIT license.

See LICENSE for more information.