ngx-skeleton-loader
Animated, accessible skeleton-loading placeholders that automatically adapt to your Angular app's UI.
Repository Health
Technical Analysis
ngx-skeleton-loader is a standalone Angular component for rendering skeleton (“ghost”) loading placeholders while real content is still fetching. Instead of a blank screen or a spinner, it shows shaped, animated bars, circles, and squares that mimic the layout of the content that’s about to appear, which is a common technique for improving perceived performance in progressive and server-side rendered apps.
The component is configurable per-instance or globally via provideNgxSkeletonLoader (standalone apps) or NgxSkeletonLoaderModule.forRoot() (NgModule apps), supporting multiple appearances (line, circle, square, custom-content), four animation styles (progress, progress-dark, pulse, pulse-dark), theme merging between root and local styles, and WAI-ARIA attributes (aria-valuetext, aria-label) for accessible loading announcements. It ships as a modern standalone Angular component with OnPush change detection and signal-based inputs.
What You Get
- A standalone
<ngx-skeleton-loader>component usable directly in templates without NgModule boilerplate - Four built-in animation styles: progress, progress-dark, pulse, and pulse-dark, plus the option to disable animation entirely
- Four appearance modes: line (default), circle, square (with configurable size/measureUnit), and custom-content for wrapping arbitrary markup
- Global and per-component theming via a
themeobject, with anextendsFromRootflag to merge root and local styles - Built-in accessibility support via configurable
aria-valuetext(loadingText) andaria-label(ariaLabel) attributes - Both standalone (
provideNgxSkeletonLoader) and NgModule (NgxSkeletonLoaderModule.forRoot()) configuration entry points
Common Use Cases
- Showing placeholder rows/cards while a list or feed loads from an API
- Wrapping a user-card or profile layout in skeletons during server-side rendering or progressive hydration
- Rendering circular avatar skeletons alongside line skeletons for text to mimic a social feed’s loading state
- Disabling animation for reduced-motion accessibility preferences while still showing layout placeholders
- Using
custom-contentappearance to animate a bespoke SVG or icon placeholder as a single DOM node
Under The Hood
Architecture
The library exposes a single standalone NgxSkeletonLoaderComponent (ngx-skeleton-loader.component.ts) with OnPush change detection and signal-based inputs (input(), computed()) rather than legacy @Input/lifecycle-hook patterns. Configuration flows through an InjectionToken (NGX_SKELETON_LOADER_CONFIG in ngx-skeleton-loader-config.types.ts), optionally injected and merged with per-instance inputs via computed items, squareSize, and styles signals. Two parallel entry points wire that token: provideNgxSkeletonLoader() for standalone apps using makeEnvironmentProviders, and NgxSkeletonLoaderModule.forRoot() for NgModule apps — both ultimately configure the same injection token, so the component’s rendering logic is decoupled from how an app chooses to bootstrap it. Changing the shared config shape would touch all three files consistently.
Tech Stack
Built on Angular 22 with TypeScript, using ng-packagr (via the @angular/build:ng-packagr builder) to produce the publishable library artifact separately from the demo app, which itself is an Angular SSR (@angular/ssr) app with an Express server for local demos. Tests run through the modern @angular/build:unit-test builder, backed by Vitest and @vitest/coverage-v8, plus a separate Playwright suite (e2e/, playwright.config.ts) for end-to-end checks. Linting uses angular-eslint and typescript-eslint via eslint.config.mjs, and coverage is reported to Coveralls in CI.
Code Quality
Each of the three library source files has a matching spec file (ngx-skeleton-loader.component.spec.ts, .module.spec.ts, .providers.spec.ts), with the component spec covering appearance variants, animation options (including invalid/false values), theme merging, and ARIA output through a wrapper test component. Error handling is minimal by design — invalid size values are guarded against with Number.isInteger checks in squareSize, and a custom-content misuse is caught with a dev-mode-only console.error rather than a thrown exception. CI runs on both CircleCI and GitHub Actions, and Prettier plus ESLint enforce consistent formatting.
API Design
The public API surface is intentionally small: one component, one config type, and two provider functions (provideNgxSkeletonLoader, NgxSkeletonLoaderModule.forRoot) covering standalone and NgModule consumers respectively. Inputs read naturally as HTML attributes (count, appearance, animation, theme, loadingText), and sensible defaults (count=1, appearance='line', animation='progress') mean a bare <ngx-skeleton-loader /> works with zero configuration. The theme.extendsFromRoot merge behavior is the one non-obvious API detail, but it’s documented with explicit before/after examples in the README.