A fully customizable React loader toolkit with theming, overlays, registry, and createLoader API.
Explore 12 beautiful loading animations, interactive examples, and comprehensive documentation on our GitHub Pages site.
- π¦ Bundle Size: < 8KB gzipped
- π Zero Dependencies: No external runtime dependencies
- βοΈ React Support: Works with React 17 and 18
- π§ TypeScript: 100% TypeScript with full type definitions
- π― Framework Agnostic: Next.js, Vite, CRA compatible
- π¨ 12 Built-in Loaders: Ready-to-use components
- Quick Stats
- Features
- Installation
- Quick Start
- Built-in Loaders
- API Reference
- Customization
- Framework Compatibility
- TypeScript Support
- Links & Resources
- Development
- Contributing
- License
- π¨ 12 Built-in Loaders: Spinner, Ring, DualRing, Dots, Bars, Pulse, Bounce, Ripple, Roller, Grid, Wave, Progress
- π― Dual API Design: Direct component usage and dynamic loader system
- πͺ Theme System: Global theming with LoaderProvider
- π Overlay System: Full-screen loading states with context integration
- π οΈ Custom Loaders: Create your own with
createLoaderfunction - π§ Registry System: Register and manage custom loaders dynamically
- π± SSR Compatible: Works with Next.js and other SSR frameworks
- π³ Tree Shakable: Import only what you need
- β‘ Lightweight: Minimal bundle size with zero dependencies
- π¨ Fully Customizable: Easy CSS override system
- π§ TypeScript First: Complete type safety and IntelliSense support
npm install react-easy-loadersImport and use any loader directly:
import { Spinner, Ring, Progress } from "react-easy-loaders";
function App() {
return (
<div>
<Spinner color="#4CAF50" size={40} />
<Ring color="#2196F3" size={50} />
<Progress color="#FF9800" size={40} progress={75} />
</div>
);
}Use the provider for consistent theming across all loaders:
import { LoaderProvider, useLoader, Spinner } from "react-easy-loaders";
function MyComponent() {
const { showLoader, hideLoader } = useLoader();
const handleClick = () => {
showLoader(<Spinner />, "Loading...");
setTimeout(hideLoader, 3000);
};
return <button onClick={handleClick}>Show Loader</button>;
}
function App() {
return (
<LoaderProvider value={{ color: "#4CAF50", size: 40, speed: 1.2 }}>
<MyComponent />
</LoaderProvider>
);
}Use the dynamic loader system to load any loader by name:
import { Loader } from "react-easy-loaders";
function App() {
return (
<div>
<Loader type="spinner" color="#4CAF50" size={50} />
<Loader type="ring" color="#2196F3" size={50} />
<Loader type="dots" color="#FF9800" size={50} />
</div>
);
}Our library includes 12 beautiful, customizable loader components:
| Component | Description | Animation Type |
|---|---|---|
<Spinner /> |
Classic spinning circle | Rotation |
<Ring /> |
Animated ring with dash | Circular stroke |
<DualRing /> |
Double concentric rings | Counter rotation |
<Dots /> |
Three bouncing dots | Vertical bounce |
<Bars /> |
Scaling rectangular bars | Height scaling |
<Pulse /> |
Pulsing circle effect | Scale transform |
<Bounce /> |
Two bouncing circles | Alternating scale |
<Ripple /> |
Water ripple effect | Expanding rings |
<Roller /> |
Rolling circles in sequence | Sequential motion |
<Grid /> |
3x3 grid of animated squares | Fade in/out |
<Wave /> |
Horizontal wave animation | Sequential bars |
<Progress /> |
Linear progress indicator | Width transition |
All loaders accept these common properties:
interface LoaderBaseProps {
color?: string; // Primary color (default: "#4b6bfb")
size?: number; // Size in pixels (default: 40)
speed?: number; // Animation speed multiplier (default: 1)
className?: string; // CSS class name
style?: CSSProperties; // Inline styles
ssrFallback?: ReactNode; // SSR fallback content
}The main provider component for global theming and overlay management:
<LoaderProvider value={{ color: "#4CAF50", size: 40 }}>
{/* Your app */}
</LoaderProvider>| Prop | Type | Default | Description |
|---|---|---|---|
value |
LoaderTheme |
{} |
Global theme configuration |
children |
ReactNode |
- | Your app components |
Hook for programmatic overlay control:
const { showLoader, hideLoader, setTheme } = useLoader();
// Show overlay loader
showLoader(<Spinner />, "Loading...");
// Hide overlay loader
hideLoader();
// Update theme
setTheme({ color: "#FF0000", size: 50 });Direct overlay component usage:
<LoaderOverlay
open={isLoading}
loader={<Spinner color="#fff" />}
message="Loading your content..."
backdropColor="rgba(0,0,0,0.7)"
zIndex={9999}
lockScroll={true}
/>Create custom loaders:
import { createLoader } from "react-easy-loaders";
const CustomLoader = createLoader(
({ color, size, speed, className, style }) => (
<div className={className} style={{ ...style, color, fontSize: size }}>
β {/* Your custom animation */}
</div>
)
);
// Use it
<CustomLoader color="gold" size={30} />;import { Loader } from "react-easy-loaders";
<Loader
type="spinner"
color="#4CAF50"
size={40}
// Any other props specific to the loader type
/>;Override CSS classes to customize appearance:
/* Global loader styles */
.loader-base {
/* Your custom styles */
}
/* Specific loader customization */
.custom-spinner {
border-width: 3px;
border-color: #your-color;
}
/* Overlay customization */
.loader-overlay {
backdrop-filter: blur(4px);
}// pages/_app.tsx
import { LoaderProvider } from "react-easy-loaders";
export default function MyApp({ Component, pageProps }) {
return (
<LoaderProvider value={{ color: "#0070f3" }}>
<Component {...pageProps} />
</LoaderProvider>
);
}// main.tsx
import { LoaderProvider } from "react-easy-loaders";
ReactDOM.createRoot(document.getElementById("root")!).render(
<LoaderProvider>
<App />
</LoaderProvider>
);Works seamlessly with Create React App, Remix, and other React frameworks.
Full TypeScript support with complete type definitions:
import type {
LoaderBaseProps,
LoaderComponent,
LoaderTheme,
OverlayProps,
} from "react-easy-loaders";
const theme: LoaderTheme = {
color: "#4CAF50",
size: 40,
speed: 1.2,
};
const customLoader: LoaderComponent = ({ color, size }) => (
<div style={{ color, fontSize: size }}>Loading...</div>
);- π Live Demo & Examples - Interactive demo with all loaders
- π¦ npm Package - Install via npm
- π GitHub Repository - Source code and issues
- π§ TypeScript Definitions - View type definitions
- π Bundle Analysis - Package size analysis
# Clone the repository
git clone https://github.com/deveshlashkari/react-easy-loaders.git
cd react-easy-loaders
# Install dependencies
npm install
# Build the package
npm run build
# Run demo locally
npm run demo:dev| Script | Description |
|---|---|
npm run build |
Build the package for production |
npm run dev |
Start demo development server |
npm run demo:build |
Build demo for production |
npm run typecheck |
Type check the codebase |
npm run clean |
Clean build artifacts |
npm run release |
Build and publish to npm |
Contributions are welcome! Here's how you can help:
- π΄ Fork the repository
- π§ Create a feature branch:
git checkout -b feature/amazing-loader - β Make your changes and test them
- π§ͺ Test in the demo:
npm run demo:dev - π Commit your changes:
git commit -m 'Add amazing loader' - π Push to the branch:
git push origin feature/amazing-loader - π Open a Pull Request
- Follow the existing code style and patterns
- Add new loaders to both the library and demo
- Update documentation as needed
- Ensure TypeScript types are properly defined
- Test your changes in multiple frameworks if possible
MIT Β© Devesh Lashkari
This project is licensed under the MIT License - see the LICENSE file for details.
function MyComponent() { const { showLoader, hideLoader } = useLoader();
const handleClick = () => { showLoader(, "Loading..."); setTimeout(hideLoader, 3000); };
return Show Loader; }
function App() { return ( <LoaderProvider value={{ color: "#4CAF50", size: 40 }}> ); }
## π Components
### Built-in Loaders
| Component | Description |
| -------------- | ----------------------- |
| `<Spinner />` | Classic spinning loader |
| `<Ring />` | Animated ring with dash |
| `<DualRing />` | Double ring animation |
| `<Dots />` | Bouncing dots |
| `<Bars />` | Scaling bars |
| `<Pulse />` | Pulsing circle |
| `<Bounce />` | Bouncing circles |
| `<Ripple />` | Water ripple effect |
| `<Roller />` | Rolling circles |
| `<Grid />` | Grid of squares |
| `<Wave />` | Wave animation |
| `<Progress />` | Progress bar |
### Core Components
- `<LoaderProvider />` - Theme provider
- `<LoaderOverlay />` - Full-screen overlay
- `<Loader />` - Dynamic loader by type
- `createLoader()` - Create custom loaders
### Hooks
- `useLoader()` - Control overlay loaders
- `useLoaderTheme()` - Access current theme
## π¨ Theming
```tsx
import { LoaderProvider } from "react-easy-loaders";
const theme = {
color: "#4CAF50",
size: 40,
speed: 1.2,
className: "my-loader",
style: { margin: "10px" },
};
function App() {
return (
<LoaderProvider value={theme}>
{/* All loaders inherit theme */}
</LoaderProvider>
);
}
import { createLoader } from 'react-easy-loaders'
const HeartLoader = createLoader(
({ color, size, speed, className, style }) => (
<div
className={className}
style={{
fontSize: size,
color,
animation: `heartbeat ${1 / speed}s ease-in-out infinite`,
...style,
}}
>
β€οΈ
<style>{`
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.2); }
}
`}</style>
</div>
)
)
// Use it
<HeartLoader color="red" size={30} speed={2} />import { Loader } from 'react-easy-loaders'
// Load any built-in loader by name
<Loader type="spinner" color="#4CAF50" size={40} />
<Loader type="ring" color="#2196F3" size={50} />
<Loader type="progress" progress={75} />import { LoaderOverlay, useLoader } from "react-easy-loaders";
// Method 1: Direct component
<LoaderOverlay
open={isLoading}
loader={<Spinner color="#fff" />}
message="Loading your content..."
backdropColor="rgba(0,0,0,0.7)"
/>;
// Method 2: Using context
function MyComponent() {
const { showLoader, hideLoader } = useLoader();
const handleLoad = async () => {
showLoader(<Ring color="#fff" />, "Please wait...");
await fetchData();
hideLoader();
};
}Run the interactive demo to see all loaders in action:
# From the project root
npm run demo:install
npm run demo:devOr visit the live demo (coming soon!)
This project is licensed under the MIT License - see the LICENSE file for details.
We welcome contributions! Please see our Contributing Guide for details.
MIT Β© Devesh Lashkari
If this project helped you, please give it a βοΈ!
Made with β€οΈ for the React community