ngx-skeleton-loader

Animated, accessible skeleton-loading placeholders that automatically adapt to your Angular app's UI.

Library
npm
v13.0.0
623stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
55/100Fair
Development Activity40
Maintenance36
Community56
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture78
Code Quality85
Innovation55
Learning Curve90

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 theme object, with an extendsFromRoot flag to merge root and local styles
  • Built-in accessibility support via configurable aria-valuetext (loadingText) and aria-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-content appearance 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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search