Network-aware skeleton loading for modern web apps.
Patch fetch and XMLHttpRequest, then drive skeleton visibility from real request lifecycle with predictable timing controls and typed hooks.
Most loading UIs rely on scattered isLoading flags and drift away from actual network behavior.
@kerothebosa/ui-skeleton-net centralizes this at the transport layer and gives you consistent skeleton timing across your app.
- Framework-agnostic runtime integration
- Intercepts both
fetchandXMLHttpRequest - Timing controls to reduce flicker (
showDelayMs,minVisibleMs) - Typed lifecycle hooks for observability and analytics
- Publish-ready distribution (
ESM,CJS,d.ts,styles.css)
npm install @kerothebosa/ui-skeleton-netimport { SkeletonEnhancer } from "@kerothebosa/ui-skeleton-net";
import "@kerothebosa/ui-skeleton-net/styles.css";
const enhancer = new SkeletonEnhancer({
skeletonSelector: "#content",
showDelayMs: 120,
minVisibleMs: 180,
requestTimeoutMs: 10_000,
timeoutMode: "abort",
enabledInterceptors: ["fetch", "xhr"]
});
enhancer.start();The stylesheet is not auto-injected by bundlers. Import it explicitly:
import "@kerothebosa/ui-skeleton-net/styles.css";| Option | Type | Purpose |
|---|---|---|
showDelayMs |
number |
Delay skeleton reveal to avoid flashing on fast requests. |
minVisibleMs |
number |
Keep skeleton visible long enough for stable perceived UX. |
requestTimeoutMs |
number |
Timeout threshold for request lifecycle handling. |
timeoutMode |
"abort" | "synthetic" |
Abort transport or only finalize UI lifecycle. |
enabledInterceptors |
Array<"fetch" | "xhr"> |
Select observed network transports. |
skeletonVisuals |
object |
Visual mode, animation, theme, and adaptive placeholder behavior. |
Full options and types:
https://kerothebosa.github.io/ui-skeleton/api-reference
const enhancer = new SkeletonEnhancer({
hooks: {
onRequestStart: ({ requestId, method, url }) =>
console.log("request:start", requestId, method, url),
onRequestEnd: ({ requestId, status, durationMs }) =>
console.log("request:end", requestId, status, durationMs),
onSkeletonShow: ({ requestId }) => console.log("skeleton:show", requestId),
onSkeletonHide: ({ requestId }) => console.log("skeleton:hide", requestId),
onError: ({ requestId, error }) => console.error("error", requestId, error.message)
}
});- Live demo: https://kerothebosa.github.io/ui-skeleton/demo/
- Local demo dev:
npm run demo:dev - Local demo preview:
npm run demo:preview
- Docs homepage: https://kerothebosa.github.io/ui-skeleton/
- Architecture: https://kerothebosa.github.io/ui-skeleton/architecture
- Lifecycle & Events: https://kerothebosa.github.io/ui-skeleton/lifecycle-and-events
- API Reference: https://kerothebosa.github.io/ui-skeleton/api-reference
- Interceptors: https://kerothebosa.github.io/ui-skeleton/interceptors
- Testing: https://kerothebosa.github.io/ui-skeleton/testing
- Playground: https://kerothebosa.github.io/ui-skeleton/playground
- Real-World Testing: https://kerothebosa.github.io/ui-skeleton/real-world-testing
- Internal docs index:
docs/README.md
- Modern browsers with
fetchandXMLHttpRequest - Node.js
>=18for tooling, CI, and local docs/demo builds
npm run build- Build package outputs (dist/)npm run demo:dev- Run local playground demonpm run docs:dev- Run VitePress docs locallynpm run ci- Lint + typecheck + tests + e2e + pack check
- Contributing:
CONTRIBUTING.md - Code of Conduct:
CODE_OF_CONDUCT.md - Security:
SECURITY.md - Changelog:
CHANGELOG.md - License:
LICENSE