Architecture
This document describes the real structure of the TSkeleton repository and how the pieces fit together.
Table of Contents
- High-level overview
- Repository layout
- Core runtime
- Components and entries
- Build pipeline
- Packaging
- Related
High-level overview
TSkeleton is a TypeScript library of loading skeleton Web Components. Each component is a custom element that renders a template string plus a shared stylesheet (SKELETON_CSS) into an open shadow root.
src/index.ts ──▶ vite (ES + CJS) ──▶ dist/tskeleton.js, dist/tskeleton.cjs
src/umd.ts ──▶ vite (UMD) ──▶ dist/tskeleton.umd.cjs
src/entries/ ──▶ vite (ES + CJS) ──▶ dist/<name>.js, dist/<name>.cjs (24 subpaths)
scripts/gen-css.mjs ───────────────▶ dist/tskeleton.css
vite-plugin-dts ──────────────────▶ dist/*.d.ts
Repository layout
TSkeleton/
├── src/
│ ├── core.ts # SKELETON_CSS, SkeletonBase, configure(), defineSkeleton()
│ ├── register.ts # REGISTRY (24 tag/class pairs) + registerAll()
│ ├── umd.ts # UMD entry: registerAll() then re-export index
│ ├── index.ts # public exports (root entry)
│ ├── demo.ts # demo playground logic
│ ├── components/ # 24 component classes (one file each)
│ └── entries/ # 24 side-effect entry points (one file each)
├── scripts/
│ ├── smoke.mjs # jsdom render test for all components
│ ├── gen-css.mjs # generates dist/tskeleton.css from the built bundle
│ ├── add-parts.mjs # maintenance helper that adds ::part() hooks to templates
│ └── generate-screenshots.py # renders Screenshots/*.png with Pillow
├── docs/ # Markdown documentation (built by MkDocs)
│ ├── index.md # docs landing page
│ └── assets/ # site assets: logo.svg, favicon.ico, screenshots/
├── Screenshots/ # generated preview images (canonical)
├── dist/ # build output (gitignored)
├── dist-demo/ # demo site build output (gitignored)
├── site/ # MkDocs output (gitignored)
├── .github/workflows/
│ ├── docs.yml # builds docs and deploys to GitHub Pages
│ └── container.yml # builds and publishes the Docker image to ghcr.io
├── *.html # original standalone template files (source material)
├── index.html # demo playground
├── vite.config.ts # main build (ES + CJS) + d.ts
├── vite.umd.config.ts # UMD build
├── vite.sub.config.ts # subpath builds (24 entries) + d.ts
├── vite.demo.config.ts # demo playground build (dist-demo/)
├── mkdocs.yml # MkDocs configuration for the docs site
├── requirements-docs.txt # Python deps for building the docs site
├── Dockerfile # multi-stage container image (demo served by nginx)
├── nginx.conf # non-root nginx config used by the image
├── tsconfig.json # strict TypeScript config
└── package.json
Core runtime
src/core.ts contains everything the components share:
SKELETON_CSS— the stylesheet string injected into every shadow root. It defines.skblocks, pulse/shimmer keyframes, cards, flex/grid helpers and sizing/spacing utilities.SkeletonBase— abstract base class. ItsconnectedCallback()attaches an open shadow root and inserts<style>SKELETON_CSS</style>plus the subclassrender()output. It also applies theme attributes. Outside the browser it falls back to a plain class so imports are SSR-safe.defineSkeleton(name, ctor)— registers a custom element, ignoring duplicates and non-browser environments.configure(theme)— sets global default CSS variables on:root.
Components and entries
src/components/ holds 24 classes, one per skeleton (for example FacebookSkeleton in facebook.ts). Every class extends SkeletonBase and implements render().
src/register.ts holds the REGISTRY of 24 [tag, class] pairs and registerAll(), which calls defineSkeleton() for each pair.
src/entries/ holds 24 entry points (for example facebook.ts). Each entry calls defineSkeleton('<tag>', Class) as a side effect and re-exports the class. These entries power the tree-shakable subpath imports (tskeleton/facebook and so on).
Build pipeline
The build script runs four steps in order:
build:main—vite build(viavite.config.ts): bundlessrc/index.tstodist/tskeleton.js(ES) anddist/tskeleton.cjs(CommonJS), and generates.d.tsfiles withvite-plugin-dts.build:umd—vite build --config vite.umd.config.ts: bundlessrc/umd.tstodist/tskeleton.umd.cjs(global nameTSkeleton).build:sub—vite build --config vite.sub.config.ts: bundles all 24 entries todist/<name>.js/dist/<name>.cjs.build:css—node scripts/gen-css.mjs: imports the built ES bundle and writesdist/tskeleton.cssfromSKELETON_CSS.
Each config uses emptyOutDir: false (except the first) so the builds write into the same dist/ directory without wiping each other.
Demo site build
npm run build:demo runs vite build --config vite.demo.config.ts, which builds the playground (index.html + src/demo.ts) into dist-demo/. This is the artifact served by the Docker image.
Documentation site
The docs site is built with MkDocs from docs/ (python -m mkdocs build) and deployed to GitHub Pages by the .github/workflows/docs.yml workflow. See Deployment.
Screenshots
scripts/generate-screenshots.py renders the preview images in Screenshots/ using Pillow. See Screenshots.
Packaging
package.json declares:
main→./dist/tskeleton.cjs,module→./dist/tskeleton.js,types→./dist/index.d.ts.unpkgandjsdelivr→./dist/tskeleton.umd.cjsfor CDN usage.exportsmap — the root plus 24 subpaths (./facebook,./github, …),./styles.css,./tskeleton.cssand./package.json.sideEffects— lists every subpath bundle so bundlers keep the registration side effects.files— onlydist, so the published tarball contains only build output plus README, LICENSE and package.json.