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

@bota-apps/auth-client

v0.6.2

Published

Cookie-based auth client for @bota-apps apps: a session endpoint, an external auth store, a root-route guard, and React bindings — composed via createAuthClient.

Readme

@bota-apps/auth-client

Cookie-session auth client for @bota-apps apps. You give it an authUrl; it gives you an AuthClient — a session endpoint, an external auth store, a root-route guard, and React bindings, all composed by createAuthClient. No tokens are read or held: the session lives in an HttpOnly cookie owned by the gateway/BFF and is resolved over a /bff/* contract.

The auth SHAPE types (AuthClient, AuthState, SessionUser, …) live in @bota-apps/types/auth and are re-exported here for convenience, so consumers import both the runtime and its types from this single package.

Install

pnpm add @bota-apps/auth-client
# peer: react

Usage

Compose the client once at bootstrap — this is the only entry point most apps need:

import { createAuthClient } from "@bota-apps/auth-client";

export const authClient = createAuthClient({ authUrl: appConfig.bffUrl });

AuthClientOptions also accepts paths to override the /bff/* contract; the default is defaultSessionPaths (/bff/{user,logout,login}).

The resulting AuthClient surface:

  • getState() / subscribe(listener) — read the current AuthState and react to changes (the store is external-store friendly).
  • ensureReady() — resolve the session once, awaitable.
  • isAuthenticated() — boolean guard derived from state.
  • logout() — clears the server session and updates state.
  • loginUrl(returnUrl?) — builds the BFF login URL (defaults the return target to the current location).
  • requireSession() — root-route guard: awaits readiness, rethrows a transport error to the app's error boundary (a network failure is not treated as "logged out"), and otherwise redirects to the login page when there is no session.

AuthState is a discriminated union on status (pending | authenticated | unauthenticated | error), so narrowing the status narrows the payload — user exists only on the authenticated member.

React bindings

Provide the client, then read it with the hooks:

import { AuthProvider, useAuth } from "@bota-apps/auth-client";

<AuthProvider client={authClient}>{children}</AuthProvider>;

function UserBadge() {
  const { user, logout, loginUrl } = useAuth();
  return user ? <button onClick={logout}>{user.name}</button> : <a href={loginUrl()}>Sign in</a>;
}

useAuthClient() returns the raw client for imperative calls; useCurrentOrganization() / useSwitchOrganization() cover the multi-org case.

Registering the app's user type

The client is generic over TUser extends SessionUser. Apps register their API-owned user type once via declaration merging against the module that declares the interface — so every surface (useAuth().user, getState()) is typed app-wide without call-site generics:

declare module "@bota-apps/types/auth" {
  interface AuthRegister {
    user: ApiUser;
  }
}

API

| Export | What | | -------------------------------------------------- | ----------------------------------------------------------------------------- | | createAuthClient | Composes endpoint + store + guard into an AuthClient bound to authUrl. | | createSessionEndpoint / defaultSessionPaths | The /bff/* session transport and its default path contract. | | createAuthStore | The external auth store (state + subscribe), guarded against stale commits. | | requireAppContext | Route-loader guard returning the typed AppContext / RootContext. | | AuthProvider / useAuth / useAuthClient | React provider and hooks over an AuthClient. | | useCurrentOrganization / useSwitchOrganization | Current-org read and switch hooks. |

Shape types (AuthClient, AuthState, AuthStatus, SessionUser, RegisteredAuthUser, SessionEndpoint, SessionPaths, and the per-status state members) are re-exported from @bota-apps/types/auth.

Part of the @bota-apps packages monorepo.