
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Minimal, lazy-initialized global state for React. Zero nested providers, true bundle splitting, useState-familiar API

Minimal, lazy-initialized global state for React. Zero nested providers, true bundle splitting, useState-familiar API
React applications inevitably accumulate global state: dark mode, user preferences, feature flags, A/B tests. The traditional solution creates a maintenance nightmare of nested Context providers:
<DomainProvider>
<FeaturesProvider>
<PreferencesProvider>
<CartProvider>
<ModalProvider>
<YourApp />
Every new feature adds another provider, every page loads all state logic regardless of usage, and your _app.tsx becomes a dumping ground for cross-team dependencies
Orbo takes a different approach: What if global state was as easy as useState, automatically lazy initialized, and completely decoupled from your app shell?
Built from the ground up for modern React applications that demand both performance and developer experience. 140 lines of code. Zero dependencies. TypeScript-first
[!WARNING] Orbo is designed specifically for singleton global states (dark mode, user preferences, feature flags, ...) -> It is not a full state management solution like Redux or Zustand
GlobalStateProvider replaces all provider nestingconst count = useCount() and setCount(5) - that's itnpm install orbo
import { createGlobalState, GlobalStateProvider } from "orbo";
// State definition stays with your component - not in _app.tsx
const [useCount, useSetCount] = createGlobalState({
initialState: () => 0,
});
function Counter() {
const count = useCount();
const setCount = useSetCount();
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
function App() {
return (
<GlobalStateProvider initialValues={{}}>
<Counter />
</GlobalStateProvider>
);
}
That's it. No provider nesting, no complex setup, no _app.tsx modifications.
Here's how you'd handle a typical dark mode implementation:
// useDarkMode.ts - lives with your component, not in _app.tsx
import { createGlobalState } from "orbo";
const [useDarkMode, useSetDarkMode] = createGlobalState({
initialState: ({ cookies }) => cookies.darkMode === "true",
});
export { useDarkMode, useSetDarkMode };
// DarkModeToggle.tsx
import { useDarkMode, useSetDarkMode } from "./useDarkMode";
export function DarkModeToggle() {
const isDark = useDarkMode();
const setDarkMode = useSetDarkMode();
return (
<button onClick={() => setDarkMode(!isDark)}>{isDark ? "🌙" : "☀️"}</button>
);
}
// _app.tsx - clean and minimal
function App({ pageProps, cookies }) {
return (
<GlobalStateProvider initialValues={{ cookies }}>
<Component {...pageProps} />
</GlobalStateProvider>
);
}
Here's a more complex example showing lifecycle management with onSubscribe and persistState:
// useServerTime.ts
import { createGlobalState } from "orbo";
const [useServerTime, useSetServerTime] = createGlobalState({
initialState: ({ serverTime }) => new Date(serverTime),
onSubscribe: (setState) => {
// Start timer when first component subscribes
const interval = setInterval(() => {
setState(new Date());
}, 1000);
// Return cleanup function
return () => {
clearInterval(interval);
};
},
// Cleanup timer when no components are using this state
persistState: false,
});
export { useServerTime };
// Clock.tsx
import { useServerTime } from "./useServerTime";
export function Clock() {
const time = useServerTime();
return <div>Current time: {time.toLocaleTimeString()}</div>;
}
// _app.tsx
function App({ pageProps }) {
return (
<GlobalStateProvider initialValues={{ serverTime: Date.now() }}>
<Component {...pageProps} />
</GlobalStateProvider>
);
}
In these examples, the logic is completely decoupled from your app shell. Components that don't use the state never load its code. New developers can understand and modify features without touching _app.tsx
Orbo provides compile-time safety through module augmentation (same pattern as styled-components):
// types.ts
// Import to enable module augmentation
import "orbo";
declare module "orbo" {
interface GlobalStateInitialValues {
cookies: { darkMode?: string };
user: { id: string; name: string } | null;
hostname: string;
}
}
// Now your initialState functions are fully typed
const [useUser] = createGlobalState({
initialState: (initialValues) => {
// initialValues.user <- TypeScript knows this exists and its shape
// initialValues.invalidProp <- TypeScript error!
return initialValues.user;
},
});
Orbo's design is based on three key insights:
This results in:
createGlobalState<T>(config)Creates a pair of hooks for reading and writing global state.
const [useValue, useSetValue] = createGlobalState({
initialState: (initialValues) => computeInitialValue(initialValues),
// Optional: sync with external sources (client-side only)
onSubscribe: (setState, currentState) => {
// Subscribe to external changes
// Optional: return cleanup function
return () => {
// Cleanup when last component unsubscribes
};
},
// Optional: keep state in memory when components unmount
persistState: true, // (default)
});
Parameters:
config.initialState: Function that receives initial values and isHydrated flag, returns the initial stateconfig.onSubscribe (optional): Function called when first component subscribes (client-side only). Receives setState and currentState. Can return a cleanup function which runs when the last component unsubscribesconfig.persistState (optional): When true, keeps state in memory after components unmount (default: true)isHydratedWhen working with client-only APIs like localStorage, sessionStorage, or browser APIs that aren't available during server-side rendering, there is the isHydrated parameter to optimize initial state handling
In general it is best practices NOT to mix SSR with client-only state as doing so creates hydrarion mismatches issues
Use the isHydrated flag only as a last resort when you absolutely must read from client-only APIs:
const [useTheme] = createGlobalState({
initialState: (initialValues, isHydrated) => {
if (!isHydrated) {
// During SSR and initial hydration: use server value to avoid mismatch
return 'light';
}
// After hydration: safe to use client-only APIs
return localStorage.getItem('theme') || 'light';
}
});
Returns:
[useGlobalState, useSetGlobalState] - React hooks for reading and writing the stateGlobalStateProviderRoot provider that manages state isolation and provides initial values
<GlobalStateProvider initialValues={{ cookies, user }}>
{children}
</GlobalStateProvider>
Props:
initialValues: Object containing initial values passed to initialState functionschildren: React childrenCheck out the /examples directory for complete implementations:
FAQs
Minimal, lazy-initialized global state for React. Zero nested providers, true bundle splitting, useState-familiar API
We found that orbo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.