@adaptive-bundle/react
v0.3.0
Published
React adapter for adaptive loading — ship different components to high and low-end devices with adaptive(), Adaptive.High/Low, and hooks.
Downloads
311
Maintainers
Readme
@adaptive-bundle/react
React adapter for adaptive loading. Ship different components to high-end and low-end devices with one-line boundaries, inline JSX conditionals, and hooks.
Install
pnpm add @adaptive-bundle/react @adaptive-bundle/core
pnpm add -D @adaptive-bundle/vite-pluginAdaptive Boundaries
Exclusion Pattern
Exclude a heavy component on low-tier devices:
import { adaptive } from '@adaptive-bundle/react';
const MapView = adaptive({
component: () => import('./MapboxMap'),
lowFallback: <img src="/static-map.png" alt="Map" />,
layout: { width: '100%', aspectRatio: '16/9' },
});Two-Variant Pattern
Ship different implementations per tier:
const Editor = adaptive({
high: () => import('./RichEditor'),
low: () => import('./BasicEditor'),
});Three-Tier Mode
const Chart = adaptive({
high: () => import('./AnimatedChart'),
medium: () => import('./StaticChart'),
low: () => import('./ChartTable'),
thresholds: { high: 0.65, low: 0.35 },
});Inline Pattern
import { Adaptive } from '@adaptive-bundle/react';
function Dashboard() {
return (
<div>
<Adaptive.High>
<AnimatedChart data={data} />
</Adaptive.High>
<Adaptive.Low>
<StaticTable data={data} />
</Adaptive.Low>
</div>
);
}Loading Strategies
Control when boundary imports are fetched:
| Strategy | Behavior |
| -------------------- | ------------------------------------------------------------------------ |
| viewport (default) | Load on first render |
| eager | Preload at definition time — use for above-the-fold content |
| lazy | Defer until element enters viewport (IntersectionObserver, 200px margin) |
// Preload critical content immediately
const Metrics = adaptive({
high: () => import('./AnimatedMetrics'),
low: () => import('./StaticMetrics'),
loading: 'eager',
});
// Defer heavy content until scrolled into view
const Scene = adaptive({
high: () => import('./ThreeScene'),
low: () => import('./StaticScene'),
loading: 'lazy',
});SSR safe: when IntersectionObserver is unavailable, lazy falls back to loading on render.
Hooks
import { useAdaptive, useTier, useDeviceProfile, useNetworkAware } from '@adaptive-bundle/react';
const { tier, shouldDefer, profile } = useAdaptive();
const tier = useTier(); // 'high' | 'low' | 'medium'
const profile = useDeviceProfile(); // full DeviceProfile
const { shouldDefer, effectiveType } = useNetworkAware();AdaptiveProvider
Cache the device profile across all hooks:
import { AdaptiveProvider } from '@adaptive-bundle/react';
<AdaptiveProvider>
<App />
</AdaptiveProvider>;Error Recovery
Boundaries automatically retry failed imports after 1 second. If a high-tier variant fails, the low variant loads as fallback.
adaptive({
high: () => import('./RichEditor'),
low: () => import('./BasicEditor'),
onError: (error, name) => analytics.track('adaptive_error', { error, name }),
});Part of Adaptive Bundle
This is the React adapter for the Adaptive Bundle monorepo. Requires @adaptive-bundle/core as a peer dependency. For build-time chunk splitting, add @adaptive-bundle/vite-plugin.
License
MIT
