@molecule/app-bonds-default-react
Feature · bonds-default · App (browser) · v1.1.2 · Apache-2.0
Default app-side bond wirings for React + Tailwind ClassMap + react-router + localStorage + fonts + icons. Per-concern setup functions plus setupAllDefaultBonds, consolidating the byte-identical per-app bond wiring across the fleet.
npm install @molecule/app-bonds-default-reactHow it works
@molecule/app-bonds-default-react is a ready-made bonds-default feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.
// 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
},
})Works with: @molecule/app-auth, @molecule/app-fonts, @molecule/app-fonts-arimo, @molecule/app-http, @molecule/app-icons, @molecule/app-icons-molecule, @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
Reference
@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 scaffoldedsrc/main.tsx: awaitssetupProviders()BEFORE the first render, kicks offauthClient.initialize()(best-effort), mounts<App />in StrictMode on#root, then registers the PWA.setupAllDefaultBonds()— wires the EIGHT universal bonds in one call: state (the vanillasimpleProvider, socreateStore()works from the first render — the documentedcreateStore()+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 viagetDefaultThemeProvider()), ui-tailwind ClassMap, icons-molecule. Each also exists as an individualsetupApp*()for apps that wire a la carte (per-appapp/src/bonds/<name>.tsfiles 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/...WithFetchClientvariants also keep the bonded http client's bearer token in sync with auth events.
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.tsJSDoc, 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.
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.
Replaces the 16-line per-app bonds/auth-default.ts that 93 fleet
apps shipped byte-identically. Apps pass their own authConfig
(which lives in src/config.ts).
function createDefaultAuthClient(authConfig: AuthClientConfig): {
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 auth events
(login / register / refresh / logout). 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.
Hydrates the HTTP client's token from the persisted auth state
on setup, then listens for auth events to keep them aligned, and holds
requests until the session restore settles so a page effect that fetches
viewer-dependent data on mount cannot race it (see registerAuthGate).
function createDefaultAuthClientWithHttpSync(authConfig: AuthClientConfig): {
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 auth events.
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
registerAuthGate), so a page that fetches viewer-dependent data on
mount cannot race it and answer for an anonymous viewer.
function createDefaultAuthClientWithFetchClient(
authConfig: AuthClientConfig,
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 (X1 flash-m65).
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^1.0.1@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.0.1@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.1react^18.0.0 || ^19.0.0react-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, notfrom '@molecule/app-bonds-default-react'. A bundler must RESOLVE everyimport()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 withRolldown 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 insidesetupProviders(make it async).bootstrapAppawaitssetupProviders()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
createDefaultAuthClientdoes NOT attach the JWT to the bonded http client. If molecule packages call authed/apiendpoints, usecreateDefaultAuthClientWithHttpSync(or...WithFetchClientto also bond a fetch client with abaseURL) — otherwise those endpoints return 401 after a page reload or token refresh. -
getDefaultThemeProvider()constructs lazily because the CSS-variables theme provider toucheslocalStorageat 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 skipsetupAppThemeCssVariables().