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

@molecule/app-bonds-default-react

v3.0.0

Published

Default app-side bond wirings for React+Tailwind+react-router+localStorage+Arimo font+molecule icons. 5 setup functions consolidating 665 byte-identical per-app bond wiring files across the fleet.

Readme

@molecule/app-bonds-default-react

@molecule/app-bonds-default-react — default app-side bond wirings for the React fleet stack, replacing the byte-identical per-app files:

  • bootstrapApp({ App, authClient, setupProviders, registerPWA? }) — the whole scaffolded src/main.tsx: awaits setupProviders() BEFORE the first render, kicks off authClient.initialize() (best-effort), mounts <App /> in StrictMode on #root, then registers the PWA.
  • setupAllDefaultBonds() — wires the EIGHT universal bonds in one call: state (the vanilla simpleProvider, so createStore() works from the first render — the documented createStore() + useStore() pattern needs a provider bonded and nothing else in a scaffold wires one), fonts-arimo, routing-react-router, storage-localstorage, styling-tailwind (registers the tailwind-merge class merger), theme-css-variables (light + dark via getDefaultThemeProvider()), ui-tailwind ClassMap, icons-molecule. Each also exists as an individual setupApp*() for apps that wire a la carte (per-app app/src/bonds/<name>.ts files stay 1-line re-exports of these).
  • Optional provider wirings live behind subpaths, one module per pair: @molecule/app-bonds-default-react/optional/<pair>.js — realtime-socketio, keyboard-shortcuts-hotkeys, command-palette-cmdk, client-search-minisearch, code-editor-monaco, virtual-scroll-tanstack, drag-drop-dndkit, charts-chartjs, maps-leaflet, video-hls. Import ONLY the ones the app installs.
  • Auth/http factories — createDefaultAuthClient(authConfig) returns { authClient, setupAuthDefault }; the ...WithHttpSync / ...WithFetchClient variants also keep the bonded http client's bearer token in sync with auth events. All three accept any JSON object profile (createDefaultAuthClient<SessionUser>(config) for an API whose user has no id) and fall back to UserProfile — with its id: string — when no type argument is given. The profile is never inferred from authConfig, so an untyped call keeps the default contract.

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Quick Start

// src/main.tsx
import {
  bootstrapApp,
  createDefaultAuthClientWithHttpSync,
  setupAllDefaultBonds,
} from '@molecule/app-bonds-default-react'
// Optional providers come from their own subpath — see @remarks.
import { setupAppCodeEditorMonaco } from '@molecule/app-bonds-default-react/optional/code-editor-monaco.js'

import { App } from './App.js'
import { authConfig } from './config.js'

const { authClient, setupAuthDefault } = createDefaultAuthClientWithHttpSync(authConfig)

bootstrapApp({
  App,
  authClient,
  // Async so optional async bonds are AWAITED before the first render.
  setupProviders: async () => {
    setupAllDefaultBonds()
    setupAuthDefault()
    await setupAppCodeEditorMonaco() // only if the app uses the code editor
  },
})

Type

feature

Installation

npm install @molecule/app-bonds-default-react @molecule/app-auth @molecule/app-charts @molecule/app-charts-chartjs @molecule/app-client-search @molecule/app-client-search-minisearch @molecule/app-code-editor @molecule/app-code-editor-monaco @molecule/app-command-palette @molecule/app-command-palette-cmdk @molecule/app-drag-drop @molecule/app-drag-drop-dndkit @molecule/app-fonts @molecule/app-fonts-arimo @molecule/app-http @molecule/app-icons @molecule/app-icons-molecule @molecule/app-keyboard-shortcuts @molecule/app-keyboard-shortcuts-hotkeys @molecule/app-maps @molecule/app-maps-leaflet @molecule/app-realtime @molecule/app-realtime-socketio @molecule/app-routing @molecule/app-routing-react-router @molecule/app-state @molecule/app-storage @molecule/app-storage-localstorage @molecule/app-styling-tailwind @molecule/app-theme @molecule/app-theme-css-variables @molecule/app-ui @molecule/app-ui-tailwind @molecule/app-video @molecule/app-video-hls @molecule/app-virtual-scroll @molecule/app-virtual-scroll-tanstack react react-dom
npm install -D @types/react @types/react-dom

API

Functions

createDefaultHttpClient(baseURL)

Builds the default fetch-based HTTP client + wires it into @molecule/app-http. Replaces the per-app bonds/http-default.ts shipped by ~52 fleet apps.

function createDefaultHttpClient(baseURL: string): {
  httpClient: HttpClient
  setupHttpDefault: () => void
}

createDefaultHttpClientWithAuthBearer(opts)

Variant of createDefaultHttpClient that adds a request interceptor injecting the JWT bearer token from the auth client AND (optionally) stripping a leading /api/ from request URLs.

Replaces ~20 per-app bonds/http-default.ts files that hand-roll this same wiring. Pass stripApiPrefix: true when the app uses baseURL: '/api' to handle pages that pass /api/-prefixed paths (would otherwise resolve to /api/api/... and 404). Pass authScheme when the API reads another scheme than Bearer: it is an option of THIS constructor (createDefaultHttpClientWithAuthBearer({ authScheme: 'Token', … }), or createFetchClient({ baseURL, authScheme: 'Token' }) directly), never a property of the client it returns. The client is built with the same scheme, so a token the client also holds — the one a default auth bond's token sync gives it — is sent with that scheme too, not as Bearer.

function createDefaultHttpClientWithAuthBearer(opts: {
  baseURL: string
  withCredentials?: boolean
  stripApiPrefix?: boolean
  getToken: () => string | null | undefined
  authScheme?: string
}): { httpClient: HttpClient; setupHttpDefault: () => void }

createDefaultAuthClient(authConfig)

Builds the default JWT auth client + wires it into @molecule/app-auth. Apps pass their own authConfig (which lives in src/config.ts).

TUser is the profile the app's pages read, and may be any JSON object type — including a profile with NO id ({ username, email, bio, image }), as in the factory it wraps. Never add a synthetic id to satisfy a type: nothing in the client reads it, and the fabricated value then travels into storage, getUser() and every page. Omit the type parameter and the default is UserProfile, whose id: string stays required — the profile is never inferred from authConfig (not even from an annotated config variable), so an untyped wrapper call keeps the default contract.

Type the config with the SAME type (const authConfig: AuthClientConfig<MyUser> = { … }) so its mapAuthResponse is checked against MyUser, and name that type at the call (createDefaultAuthClient<MyUser>(authConfig)): a mapper that omits a required custom field then fails at that call instead of shipping a signed-in page that reads undefined. An annotated config alone does not supply the type argument — that is a 1.8 caller shape this major changes (see AuthClientConfig's migration note in @molecule/app-auth).

TRegister is the app's own registration fields ({ username: string } for a RealWorld-shaped API), passed on to @molecule/app-auth's factory so authClient.register({ username, email, password }) type-checks with no cast.

function createDefaultAuthClient(authConfig: NoInfer<AuthClientConfigOptions<TUser>>): {
  authClient: AuthClient<TUser, TRegister>
  setupAuthDefault: () => void
}

createDefaultAuthClientWithHttpSync(authConfig)

Variant of createDefaultAuthClient that also keeps the bonded @molecule/app-http client's bearer token in sync with the auth client's session. Required by apps whose http client must carry the JWT on every request — without this wiring, authed endpoints return 401 after page reloads or token refresh.

The sync is a LIVE read: @molecule/app-http's setAuthTokenSource registers the auth client's token, and every client the app bonds — one bonded after this setup too (the scaffold wires auth BEFORE http, so a token copied into the client present at setup was never sent) — reads it on each request. A session adopted with no auth event (useAuth().setSession(), an OAuth callback's setAccessToken(), the same profile under a new token) is therefore sent by the next request, not the previous account's bearer. A transport without setAuthTokenResolver is followed through a request interceptor (see setAuthTokenSource for which request first carries the change), and auth events still push the token to it.

A cookie session (no body token) resolves to null, so the request carries NO Authorization header — a kept bearer would answer as the PRIOR session. Requests also wait for the session restore, so a page that fetches viewer data on mount cannot race it (see {@link registerAuthGate}).

The profile type is createDefaultAuthClient's: a JSON object type of named fields (see AuthProfileShape), including an app profile with no id.

function createDefaultAuthClientWithHttpSync(authConfig: NoInfer<AuthClientConfigOptions<TUser>>): {
  authClient: AuthClient<TUser, TRegister>
  setupAuthDefault: () => void
}

createDefaultAuthClientWithFetchClient(authConfig, fetchClientOptions)

Most aggressive variant — bonds a fetch-based HTTP client with the given baseURL (so molecule pkg useGet('/path') calls hit ${baseURL}/path instead of the SPA's catch-all route), AND keeps its bearer token in sync with the auth client's session, read on every request: a session adopted with no auth event (setSession(), setAccessToken()) is sent by the next request. The token uses the auth config's authScheme (default Bearer); a client bonded after this setup gets the same source and auth events.

The auth client restores a stored token AND user SYNCHRONOUSLY, so the first render is the signed-in UI — do not gate a protected page (or a provider of yours) on a current-user request. This bond registers whenRestored() as the HTTP gate, so requests still wait for the background restore/verification to settle; only useAuth().status === 'loading' means "no decision yet" (a page that waits on its own /me pays a round trip on every navigation).

Used by apps where molecule packages render pricing / billing / other authed JSON-fetching screens that need both behaviors.

Requests are also held until the session restore settles (see {@link registerAuthGate}), so a page that fetches viewer-dependent data on mount cannot race it and answer for an anonymous viewer.

The profile type is createDefaultAuthClient's: a JSON object type of named fields (see AuthProfileShape), including an app profile with no id.

function createDefaultAuthClientWithFetchClient(
  authConfig: NoInfer<AuthClientConfigOptions<TUser>>,
  fetchClientOptions: { baseURL: string; withCredentials?: boolean },
): { authClient: AuthClient<TUser, TRegister>; setupAuthDefault: () => void }

bootstrapApp(opts)

Boot the React app: wire bonds, kick off auth initialization, mount <App /> inside <StrictMode> to #root, and (optionally) register the PWA service worker.

Replaces the 20-line per-app src/main.tsx that 97 fleet apps shipped byte-identically.

function bootstrapApp(opts: {
  App: ComponentType
  authClient: { initialize: () => Promise<void> }
  setupProviders: () => void | Promise<void>
  registerPWA?: () => void
}): void

getDefaultThemeProvider()

Returns (and lazily constructs) the shared default CSS-variables theme provider.

function getDefaultThemeProvider(): ThemeProvider

setupAppFontsArimo()

Wires @molecule/app-fonts-arimo to @molecule/app-fonts.

function setupAppFontsArimo(): void

setupAppIconsMolecule()

Wires @molecule/app-icons-molecule to @molecule/app-icons.

function setupAppIconsMolecule(): void

setupAppRoutingReactRouter()

Wires @molecule/app-routing-react-router to @molecule/app-routing.

function setupAppRoutingReactRouter(): void

setupAppStateSimple()

Wires the framework-agnostic simpleProvider from @molecule/app-state as the active state provider.

WITHOUT this, createStore() throws @molecule/app-state: No provider set. Call setProvider() first — nothing else in a scaffolded app wires the state bond, so the documented createStore() + useStore() pattern failed at the first render and every page came up blank while tsc passed.

function setupAppStateSimple(): void

setupAppStorageLocalstorage()

Wires @molecule/app-storage-localstorage to @molecule/app-storage.

function setupAppStorageLocalstorage(): void

setupAppStylingTailwind()

Wires @molecule/app-styling-tailwind: registers tailwind-merge as the class merger for @molecule/app-styling's cn(), so conflicting Tailwind utilities resolve (last wins). Tailwind itself is configured via env vars + the Vite plugin; this is the one runtime hook the framework-agnostic styling core needs so it carries no Tailwind dependency of its own.

function setupAppStylingTailwind(): void

setupAppThemeCssVariables()

Wires the default light + dark CSS-variables theme provider to @molecule/app-theme.

function setupAppThemeCssVariables(): void

setupAppUiTailwind()

Wires @molecule/app-ui-tailwind classMap to @molecule/app-ui.

function setupAppUiTailwind(): void

setupAllDefaultBonds()

Wires all 8 universal app-side bonds in one call — state (the vanilla simpleProvider, so createStore() works), fonts, routing, storage, styling, theme, UI ClassMap, icons (in that order). Auth + i18n stay per-app because they need app-specific config.

Replaces the individual setupX() calls in per-app bonds/index.ts.

function setupAllDefaultBonds(): void

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-auth ^3.0.0
  • @molecule/app-charts ^1.0.1
  • @molecule/app-charts-chartjs ^1.0.1
  • @molecule/app-client-search ^1.0.0
  • @molecule/app-client-search-minisearch ^1.0.0
  • @molecule/app-code-editor ^1.0.1
  • @molecule/app-code-editor-monaco ^1.0.1
  • @molecule/app-command-palette ^1.0.1
  • @molecule/app-command-palette-cmdk ^1.0.1
  • @molecule/app-drag-drop ^1.0.1
  • @molecule/app-drag-drop-dndkit ^1.0.1
  • @molecule/app-fonts ^1.0.1
  • @molecule/app-fonts-arimo ^1.0.1
  • @molecule/app-http ^1.5.0
  • @molecule/app-icons ^1.0.1
  • @molecule/app-icons-molecule ^1.0.1
  • @molecule/app-keyboard-shortcuts ^1.0.1
  • @molecule/app-keyboard-shortcuts-hotkeys ^1.0.1
  • @molecule/app-maps ^1.0.1
  • @molecule/app-maps-leaflet ^1.0.1
  • @molecule/app-realtime ^1.0.1
  • @molecule/app-realtime-socketio ^1.0.1
  • @molecule/app-routing ^1.0.1
  • @molecule/app-routing-react-router ^1.0.1
  • @molecule/app-state ^1.0.1
  • @molecule/app-storage ^1.0.1
  • @molecule/app-storage-localstorage ^1.0.1
  • @molecule/app-styling-tailwind ^1.0.1
  • @molecule/app-theme ^1.0.1
  • @molecule/app-theme-css-variables ^1.0.1
  • @molecule/app-ui ^1.0.1
  • @molecule/app-ui-tailwind ^1.0.1
  • @molecule/app-video ^1.0.1
  • @molecule/app-video-hls ^1.0.1
  • @molecule/app-virtual-scroll ^1.0.1
  • @molecule/app-virtual-scroll-tanstack ^1.0.1
  • react ^18.0.0 || ^19.0.0
  • react-dom ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-auth

  • @molecule/app-charts

  • @molecule/app-charts-chartjs

  • @molecule/app-client-search

  • @molecule/app-client-search-minisearch

  • @molecule/app-code-editor

  • @molecule/app-code-editor-monaco

  • @molecule/app-command-palette

  • @molecule/app-command-palette-cmdk

  • @molecule/app-drag-drop

  • @molecule/app-drag-drop-dndkit

  • @molecule/app-fonts

  • @molecule/app-fonts-arimo

  • @molecule/app-http

  • @molecule/app-icons

  • @molecule/app-icons-molecule

  • @molecule/app-keyboard-shortcuts

  • @molecule/app-keyboard-shortcuts-hotkeys

  • @molecule/app-maps

  • @molecule/app-maps-leaflet

  • @molecule/app-realtime

  • @molecule/app-realtime-socketio

  • @molecule/app-routing

  • @molecule/app-routing-react-router

  • @molecule/app-state

  • @molecule/app-storage

  • @molecule/app-storage-localstorage

  • @molecule/app-styling-tailwind

  • @molecule/app-theme

  • @molecule/app-theme-css-variables

  • @molecule/app-ui

  • @molecule/app-ui-tailwind

  • @molecule/app-video

  • @molecule/app-video-hls

  • @molecule/app-virtual-scroll

  • @molecule/app-virtual-scroll-tanstack

  • react

  • react-dom

  • Optional setups are NOT exported from the package root. Import each from its own subpath — @molecule/app-bonds-default-react/optional/maps-leaflet.js, not from '@molecule/app-bonds-default-react'. A bundler must RESOLVE every import() in a module it pulls into the graph, before tree-shaking can drop anything, so while these lived in the barrel every app inherited all 18 optional providers and any app that had not installed all of them failed to build with Rolldown failed to resolve import "@molecule/app-maps". Only import a subpath whose provider pair the app actually installs.

  • setupAllDefaultBonds() does NOT wire the optional bonds. Those ship as separate ASYNC setups — setupAppRealtimeSocketio, setupAppKeyboardShortcutsHotkeys, setupAppCommandPaletteCmdk, setupAppCodeEditorMonaco, setupAppVirtualScrollTanstack, setupAppDragDropDndkit, setupAppChartsChartjs, setupAppMapsLeaflet, setupAppVideoHls — and MUST be awaited inside setupProviders (make it async). bootstrapApp awaits setupProviders() before mounting so bonded providers exist by a component's first effect; a fire-and-forget async setup races the mount and intermittently loses.

  • Plain createDefaultAuthClient does NOT attach the JWT to the bonded http client. If molecule packages call authed /api endpoints, use createDefaultAuthClientWithHttpSync (or ...WithFetchClient to also bond a fetch client with a baseURL) — otherwise those endpoints return 401 after a page reload or token refresh.

  • getDefaultThemeProvider() constructs lazily because the CSS-variables theme provider touches localStorage at construction — importing this package is SSR/test-safe, but only CALL it in a DOM environment. Apps with custom themes build their own provider and skip setupAppThemeCssVariables().