@adaptive-bundle/svelte
v0.3.0
Published
Svelte adapter for adaptive loading — ship different components to high and low-end devices with adaptive() stores and context.
Maintainers
Readme
@adaptive-bundle/svelte
Svelte adapter for adaptive loading. Ship different components to high-end and low-end devices with adaptive() stores and Svelte context.
Install
pnpm add @adaptive-bundle/svelte @adaptive-bundle/core
pnpm add -D @adaptive-bundle/vite-pluginAdaptive Boundaries
Two-Variant Pattern
<script>
import { adaptive } from '@adaptive-bundle/svelte';
const MapView = adaptive({
high: () => import('./MapboxMap.svelte'),
low: () => import('./StaticMap.svelte'),
});
</script>
{#if $MapView}
<svelte:component this={$MapView} center={[40, -3]} zoom={12} />
{/if}adaptive() returns a Svelte Readable store that lazily loads the correct variant on first subscription.
Exclusion Pattern
const MapView = adaptive({
component: () => import('./MapboxMap.svelte'),
});
// Returns null on low-tier devicesThree-Tier Mode
const Chart = adaptive({
high: () => import('./AnimatedChart.svelte'),
medium: () => import('./StaticChart.svelte'),
low: () => import('./ChartTable.svelte'),
thresholds: { high: 0.65, low: 0.35 },
});Loading Strategies
| Strategy | Behavior |
| -------------------- | -------------------------------------------------------------------- |
| viewport (default) | Load on first render |
| eager | Preload at definition time |
| lazy | Returns a LazyReadable — import deferred until .load() is called |
<script>
import { adaptive, viewportAction } from '@adaptive-bundle/svelte';
// Eager: preload immediately
const Metrics = adaptive({
high: () => import('./AnimatedMetrics.svelte'),
low: () => import('./StaticMetrics.svelte'),
loading: 'eager',
});
// Lazy: defer until scrolled into view
const Scene = adaptive({
high: () => import('./ThreeScene.svelte'),
low: () => import('./StaticScene.svelte'),
loading: 'lazy',
});
</script>
<!-- Use viewportAction to trigger lazy loading -->
<div use:viewportAction={() => Scene.load()}>
{#if $Scene}
<svelte:component this={$Scene} />
{/if}
</div>The viewportAction Svelte action uses IntersectionObserver with a 200px root margin. SSR safe: calls loadFn immediately when IntersectionObserver is unavailable.
Stores
import { tierStore, deviceProfileStore, networkAwareStore } from '@adaptive-bundle/svelte';
$tierStore; // 'high' | 'low' | 'medium'
$deviceProfileStore; // full DeviceProfile
$networkAwareStore; // { shouldDefer, effectiveType }Context
Share the device profile across a component tree:
import { setAdaptiveContext, getAdaptiveContext } from '@adaptive-bundle/svelte';
// In a parent component
setAdaptiveContext();
// In any child component
const profile = getAdaptiveContext();Part of Adaptive Bundle
This is the Svelte adapter for the Adaptive Bundle monorepo. Requires @adaptive-bundle/core as a peer dependency and Svelte 4+. For build-time chunk splitting, add @adaptive-bundle/vite-plugin.
License
MIT
