Framework-agnostic, fully customizable loading skeleton Web Components.
TSkeleton is a zero-dependency library of ready-made loading skeleton Web Components inspired by popular apps — Facebook, GitHub, Twitter (X), Instagram, Threads, WhatsApp, TikTok, LinkedIn, Messenger, YouTube, Telegram, Meta Business, MyGP and Google.
Each skeleton is a self-contained custom element with its own shadow DOM and built-in pulse and shimmer animations. Because the components are plain Web Components, they work in any framework (React, Vue, Svelte, Angular) and in plain HTML, via npm or a CDN.
More screenshots: View all screenshots
- Key Features
- Installation
- Quick Start
- Usage Examples
- Documentation
- Interface
- Architecture
- Requirements
- Prerequisites
- Development
- Contributing
- Security
- License
- Acknowledgments
- 24 ready-made skeletons — tags such as
<skeleton-facebook>,<skeleton-tiktok>and<skeleton-youtube>cover popular apps out of the box. - Framework-agnostic — standard custom elements with open shadow DOM; no Tailwind, CSS framework or runtime dependency required.
- Zero dependencies — the published package ships no runtime dependencies.
- Three-level theming — global
configure()API, per-instance attributes, and CSS variables with::part()styling hooks. - Tree-shakable subpaths — import
tskeleton/facebookto register only that component. - Multiple formats — ES, CommonJS and UMD bundles plus a standalone
tskeleton.css. - SSR-safe — importing the package does not touch
HTMLElementorcustomElementsoutside the browser. - TypeScript — strict-typed with generated declaration files.
- Live demo playground —
npm run devstarts a playground with real-time theme controls.
npm install tskeleton
# or
yarn add tskeleton
# or
pnpm add tskeletonNote: the package is not published to the npm registry yet. Until it is, install directly from GitHub:
npm install github:rkriad585/TSkeleton
Load the UMD bundle from a CDN — it registers every component automatically:
<script src="https://unpkg.com/tskeleton@0.2.0/dist/tskeleton.umd.cjs"></script>The bundle exposes a global TSkeleton object (registerAll, SkeletonBase, configure, SKELETON_CSS and every component class).
<script src="https://unpkg.com/tskeleton@0.2.0/dist/tskeleton.umd.cjs"></script>
<skeleton-facebook></skeleton-facebook>
<skeleton-google></skeleton-google>In a bundler-based project:
import { registerAll } from 'tskeleton'
registerAll()<skeleton-github></skeleton-github>import 'tskeleton/facebook' // registers <skeleton-facebook> as a side effect
import { FacebookSkeleton } from 'tskeleton/facebook'import { useEffect } from 'react'
import { registerAll } from 'tskeleton'
export default function Loading() {
useEffect(() => { registerAll() }, [])
return <skeleton-facebook />
}
registerAll()is idempotent — duplicate definitions are ignored, so it is safe to call from every component that renders a skeleton.
<script setup>
import { onMounted } from 'vue'
import { registerAll } from 'tskeleton'
onMounted(() => registerAll())
</script>
<template>
<skeleton-youtube />
</template>import { configure } from 'tskeleton'
configure({
color: '#e5e7eb',
colorDark: '#d1d5db',
colorLight: '#f3f4f6',
highlight: 'rgba(255,255,255,.6)',
radius: '4px',
duration: '2s',
cardBg: '#ffffff',
cardRadius: '8px',
})<skeleton-facebook
variant="shimmer"
color="#f43f5e"
color-dark="#fb7185"
color-light="#ffe4e6"
duration="1.2s"
></skeleton-facebook>import { defineSkeleton, SkeletonBase } from 'tskeleton'
class MySkeleton extends SkeletonBase {
render() {
return `
<div class="sk-card sk-p-4 sk-flex sk-gap-3">
<div class="sk sk--circle sk-w-12 sk-h-12"></div>
<div class="sk-flex-1">
<div class="sk sk-h-4 sk-w-50 sk-mb-2"></div>
<div class="sk sk-h-3 sk-w-75"></div>
</div>
</div>`
}
}
defineSkeleton('skeleton-mine', MySkeleton)| Document | Description |
|---|---|
| Getting Started | First steps with TSkeleton |
| Installation | Install via npm, package manager or CDN |
| Usage | Usage in HTML, bundlers and frameworks |
| API Reference | Exports, attributes, CSS variables and parts |
| Configuration | Theming guide |
| Architecture | Project structure and build pipeline |
| Development | Building, testing and publishing locally |
| Deployment | Publishing and CDN distribution |
| Screenshots | Screenshot gallery |
| FAQ | Frequently asked questions |
| Troubleshooting | Common problems and fixes |
A rendered copy of this documentation is deployed to GitHub Pages and lives at https://rkriad585.github.io/TSkeleton/ (built automatically from the docs/ folder by the Docs workflow).
TSkeleton is a Web Component library. Its public interface is a set of custom elements plus a small JavaScript API.
Custom elements (registered via registerAll() or subpath imports):
<skeleton-facebook> <skeleton-github>
<skeleton-twitter> <skeleton-instagram>
<skeleton-threads> <skeleton-whatsapp>
<skeleton-tiktok> <skeleton-linkedin>
<skeleton-tiktok-foryou> <skeleton-tiktok-profile>
<skeleton-tiktok-chats> <skeleton-messenger>
<skeleton-facebook-profile> <skeleton-facebook-settings>
<skeleton-youtube> <skeleton-youtube-reels>
<skeleton-youtube-subs> <skeleton-telegram>
<skeleton-telegram-profile> <skeleton-meta-business>
<skeleton-yt-studio> <skeleton-mygp>
<skeleton-google> <skeleton-bonus>JavaScript API (from tskeleton):
registerAll()— registers every component once.defineSkeleton(name, ctor)— registers a single component.configure(theme)— sets a global default theme.SkeletonBase— base class for building custom skeletons.SKELETON_CSS— the shared skeleton stylesheet as a string.
See the API Reference for the full details, attribute table and CSS variable list.
TSkeleton/
├── src/
│ ├── core.ts # SKELETON_CSS, SkeletonBase, configure(), defineSkeleton()
│ ├── register.ts # REGISTRY + registerAll()
│ ├── umd.ts # UMD entry: registers all, re-exports index
│ ├── index.ts # public exports
│ ├── demo.ts # demo playground logic
│ ├── components/ # 24 skeleton component classes
│ └── entries/ # 24 side-effect entry points (one per component)
├── scripts/
│ ├── smoke.mjs # jsdom render test
│ ├── gen-css.mjs # generates dist/tskeleton.css
│ └── add-parts.mjs # maintenance helper that adds ::part() hooks
├── dist/ # build output (gitignored)
├── *.html # original standalone template files
├── index.html # demo playground
└── package.json
Each component class extends SkeletonBase, which renders the shared stylesheet and the component template into an open shadow root. The build pipeline emits ES, CommonJS and UMD bundles from vite.config.ts, vite.umd.config.ts and vite.sub.config.ts.
- A modern browser with Web Components support (custom elements and shadow DOM) — Chrome, Edge, Firefox and Safari, current versions.
- Node.js >= 18 and npm only if you build the library or run the demo.
- Node.js >= 18 (see package.json
engines). - npm (bundled with Node.js).
git clone https://github.com/rkriad585/TSkeleton.git
cd TSkeleton
npm install
npm run dev # demo playground at http://localhost:5173
npm run typecheck # TypeScript type check
npm run build # ES + CJS + UMD bundles, subpath builds and tskeleton.css
npm run smoke # jsdom render test for all 24 components
npm test # typecheck + build + smokeContributions are welcome. Please read CONTRIBUTING.md and the Code of Conduct before opening an issue or pull request.
Please report security issues as described in SECURITY.md.
Distributed under the MIT License.
- Inspired by the loading placeholders of Facebook, GitHub, Twitter (X), Instagram, Threads, WhatsApp, TikTok, LinkedIn, Messenger, YouTube, Telegram, Meta Business, MyGP and Google.
- Built with Vite and TypeScript.
