https://github.com/shiftbloom-studio/birthday-cake-loading
Birthday‑Cake Loading (BCL) is a capability‑adaptive progressive enhancement toolkit for React and Next.js. It ships a tiny baseline runtime, detects device/network/user‑preference signals, and lazily upgrades experiences only when the runtime has enough budget.
https://github.com/shiftbloom-studio/birthday-cake-loading
lazy-loading nextjs react
Last synced: 3 months ago
JSON representation
Birthday‑Cake Loading (BCL) is a capability‑adaptive progressive enhancement toolkit for React and Next.js. It ships a tiny baseline runtime, detects device/network/user‑preference signals, and lazily upgrades experiences only when the runtime has enough budget.
- Host: GitHub
- URL: https://github.com/shiftbloom-studio/birthday-cake-loading
- Owner: shiftbloom-studio
- License: apache-2.0
- Created: 2026-01-01T13:32:09.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-01-15T01:56:38.000Z (6 months ago)
- Last Synced: 2026-01-15T07:56:51.434Z (6 months ago)
- Topics: lazy-loading, nextjs, react
- Language: TypeScript
- Homepage: https://birthday-cake-loading-demo.vercel.app
- Size: 704 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# 🎂 **Birthday-Cake Loading (BCL)**
**Capability-first progressive enhancement for React + Next.js.**
**Why BCL?**
- ⚡ **Fast time-to-content** with baseline-first rendering.
- 🧁 **True progressive enhancement** (upgrade only when the device can afford it).
- ♿ **Accessibility-first** with reduced-motion/data respect built in.
- 🌿 **Respects user preferences** (`Save-Data`, `prefers-reduced-*`).
- 🪶 **Tiny runtime** and tree-shakeable exports.
- ✅ **Next.js-ready** with a zero-config feel.
[](https://www.npmjs.com/package/@shiftbloom-studio/birthday-cake-loading)
[](https://www.npmjs.com/package/@shiftbloom-studio/birthday-cake-loading)
[](LICENSE)
[](https://github.com/fabianzimber/birthday-cake-loading)
[](https://github.com/fabianzimber/birthday-cake-loading/actions)
## 🚀 Quickstart
```bash
npm install @shiftbloom-studio/birthday-cake-loading
```
```tsx
"use client";
import {
CakeProvider,
CakeWatch,
CakeLayer,
CakeUpgrade,
useCakeFeatures
} from "@shiftbloom-studio/birthday-cake-loading";
const MotionStatus = () => {
const { motion } = useCakeFeatures();
return
Motion: {String(motion)}
;
};
export default function Page() {
return (
Static hero}>
Animated hero
import("./rich-gallery")}
fallback={
Static gallery}
/>
);
}
```
## ✨ Key Features
| Feature | What you get | Why it matters |
| --- | --- | --- |
| Tiering (`base → ultra`) | Signal-driven capability buckets | Predictable, conservative upgrades |
| Feature flags | `motion`, `richImages`, `audio`, etc. | Easy gating without bespoke logic |
| SSR/Client Hints | `@shiftbloom-studio/birthday-cake-loading/server` helpers | Fast first paint, consistent tiering |
| `CakeLayer` + `CakeUpgrade` | Render/lazy-load by tier | Smooth progressive enhancement |
| Overrides + DevTools | Session override + in-app panel | QA and demos become trivial |
## 🆚 Comparison
| Approach | Bundle impact | Accessibility | Progressive enhancement | Server-first |
| --- | --- | --- | --- | --- |
| BCL | **Tiny** | **Built-in** | **Automatic** | **Yes** |
| Manual feature flags | Medium | Manual | Manual | Optional |
| Device sniffing | Medium | Inconsistent | Risky | Optional |
| “Everything on” | Large | Often skipped | None | No |
## 🧠 How tiering decides
```mermaid
flowchart TD
A[Signals: data saver, memory, CPU, network] --> B{Save-Data or very low memory?}
B -- yes --> C[base]
B -- no --> D{Low memory/cores or constrained network?}
D -- yes --> E[lite]
D -- no --> F{High memory + high cores?}
F -- yes --> G[ultra]
F -- no --> H[rich]
```
## 📡 Signal flow
```mermaid
flowchart LR
Headers[Client Hints / Headers] --> Server[server helpers]
Server --> Provider[CakeProvider bootstrap]
Provider --> Tiering[Tier + Features]
Tiering --> UI[Layered UI]
```
## 🧩 Optional Signal Matrix (privacy-safe tuning)
For known device/browser quirks (ex: animation issues on certain mobile setups), BCL can apply
an **optional, coarse signal matrix** that nudges tiers without invasive fingerprinting.
```tsx
{children}
```
The built-in matrix uses only **non-unique** signals (reduced motion/data, coarse
memory/CPU, mobile hint, and network class) and can be overridden by ID.
## 🔌 Server bootstrap (Next.js)
```ts
import { getServerCakeBootstrapFromHeaders } from "@shiftbloom-studio/birthday-cake-loading/server";
const bootstrap = getServerCakeBootstrapFromHeaders(headers());
```
## 🛰️ CakeWatchtower (runtime jank guard)
`CakeWatch` is an opt-in component that listens for frame drops + long tasks. When jank is
detected, it can temporarily downgrade specific rich layers to their static fallbacks (no layout
flicker by default thanks to opacity swaps).
```tsx
import { CakeProvider, CakeWatch, CakeLayer } from "@shiftbloom-studio/birthday-cake-loading";
export default function App() {
return (
Static background}>
Particles + motion
);
}
```
```tsx
// app/layout.tsx
import { headers } from "next/headers";
import { getServerCakeBootstrapFromHeaders } from "@shiftbloom-studio/birthday-cake-loading/server";
export default function RootLayout({ children }: { children: React.ReactNode }) {
const bootstrap = getServerCakeBootstrapFromHeaders(headers());
return (
{children}
);
}
```
## 🧪 Testing
```bash
npm test
```
## 📜 License
MIT License