npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

grab-n-drag-infinite-carousel

v1.1.1

Published

A lightweight, dependency-free infinite scrolling carousel component with grab-and-drag interaction, momentum scrolling, and seamless looping

Readme

Grab-n-Drag Infinite Scrolling Carousel

A lightweight, dependency-free JavaScript library for creating smooth infinite scrolling carousels with grab-and-drag interaction.

Perfect for showcasing logos, skills, testimonials, or any scrollable content. Features seamless looping, natural momentum physics, and full touch support, all packed into a tiny ~30KB package.

npm version CI npm downloads GitHub issues License

Demo

Demo GIF of Infinite Scrolling Carousel

View interactive examples with code →

Features

  • Infinite Seamless Loop - Automatically duplicates items for continuous scrolling with no visible jumps
  • Grab and Drag - Interactive dragging with mouse and touch support
  • Momentum Scrolling - Natural momentum physics after drag release
  • Pause on Hover - Optional pause when hovering over the carousel
  • Event Callbacks - Hook into lifecycle events and user interactions
  • Zero Dependencies - Pure vanilla JavaScript, no jQuery or frameworks required
  • Lightweight - Works in all modern browsers
  • HTML Accessible - Maintains keyboard navigation and screen reader compatibility

Bundle Size

  • JavaScript (minified): 16.9kB
  • CSS (minified): 4.9kB
  • Package Size: ~30kB
  • Zero dependencies - No additional bundle weight

Installation

npm (Recommended)

npm install grab-n-drag-infinite-carousel

Then import using one of the following:

// ES Modules (development - unminified)
import InfiniteScrollCarousel from 'grab-n-drag-infinite-carousel';
import 'grab-n-drag-infinite-carousel/grab-n-drag-infinite-carousel.css';

// ES Modules (production - minified)
import InfiniteScrollCarousel from 'grab-n-drag-infinite-carousel/dist/grab-n-drag-infinite-carousel.min.js';
import 'grab-n-drag-infinite-carousel/dist/grab-n-drag-infinite-carousel.min.css';

// CommonJS (development - unminified)
const InfiniteScrollCarousel = require('grab-n-drag-infinite-carousel');
require('grab-n-drag-infinite-carousel/grab-n-drag-infinite-carousel.css');

// CommonJS (production - minified)
const InfiniteScrollCarousel = require('grab-n-drag-infinite-carousel/dist/grab-n-drag-infinite-carousel.min.js');
require('grab-n-drag-infinite-carousel/dist/grab-n-drag-infinite-carousel.min.css');

CDN

<!-- CSS (development - unminified) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/grab-n-drag-infinite-carousel@latest/grab-n-drag-infinite-carousel.css">
<!-- CSS (production - minified) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/grab-n-drag-infinite-carousel@latest/dist/grab-n-drag-infinite-carousel.min.css">

<!-- JavaScript (development - unminified) -->
<script src="https://cdn.jsdelivr.net/npm/grab-n-drag-infinite-carousel@latest/grab-n-drag-infinite-carousel.js"></script>
<!-- JavaScript (production - minified) -->
<script src="https://cdn.jsdelivr.net/npm/grab-n-drag-infinite-carousel@latest/dist/grab-n-drag-infinite-carousel.min.js"></script>

Manual Download

Download the files directly from npm or this repository:

Development (unminified):

  • grab-n-drag-infinite-carousel.js
  • grab-n-drag-infinite-carousel.css

Production (minified):

  • dist/grab-n-drag-infinite-carousel.min.js
  • dist/grab-n-drag-infinite-carousel.min.css

TypeScript Support

TypeScript definitions are included! If you're using TypeScript, you'll get full type checking and IntelliSense support:

import InfiniteScrollCarousel, { InfiniteScrollCarouselOptions } from 'grab-n-drag-infinite-carousel';

const options: InfiniteScrollCarouselOptions = {
  speed: 50,
  pauseOnHover: true
};

const carousel = new InfiniteScrollCarousel('#myCarousel', options);

Quickstart

HTML

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="grab-n-drag-infinite-carousel.css">
</head>
<body>
    <div class="infinite-scroll-wrapper">
        <div class="infinite-scroll-container" id="myCarousel">
            <div class="infinite-scroll-item">Item 1</div>
            <div class="infinite-scroll-item">Item 2</div>
            <div class="infinite-scroll-item">Item 3</div>
            <!-- Add more items as needed -->
        </div>
    </div>

    <script src="grab-n-drag-infinite-carousel.js"></script>
    <script>
        const container = document.querySelector('#myCarousel');
        const carousel = new InfiniteScrollCarousel(container, {
            speed: 50
        });
    </script>
</body>
</html>

That's it! The carousel will automatically start scrolling.

API Reference

Constructor

new InfiniteScrollCarousel(container, options)

Parameters:

  • container (HTMLElement or string) - The container element or CSS selector
  • options (Object, optional) - Configuration object

Options

| Option | Type | Default | Description | |------|------|---------|-------------| | speed | number | 50 | Auto-scroll speed (pixels/sec). Set to 0 to disable auto-scroll. | | reverseDirection | boolean | false | Scroll direction. false: right to left ←, true: left to right → | | pauseOnHover | boolean | true | Pauses scrolling when the pointer hovers an element. | | momentumDecay | number | 0.05 | Drag momentum decay rate (Range: 0.01–0.5). Higher values decay quicker. | | maxMomentumSpeed | number | 2.0 | Maximum momentum speed in px/ms (Range: 0.5–25). | | fadeColor | string | #ffffff | Edge fade color (hex, rgb, rgba). Use transparent to disable. | | fadeWidth | number | 50 | Width of the fade gradient in pixels. | | interactable | boolean | true | Enable grab-and-drag interaction. Set to false to disable dragging. | | copies | number | 3 | Number of duplicated item sets for seamless looping. |

Event Callbacks

| Callback | Type | Description | |----------|------|-------------| | onReady | () => void | Fires when carousel initialization completes | | onDragStart | () => void | Fires when user starts dragging | | onDrag | (position: number, deltaX: number) => void | Fires during drag movement (throttled) | | onDragEnd | () => void | Fires when user ends dragging | | onMomentumStart | (velocity: number) => void | Fires when momentum scrolling begins | | onMomentumEnd | () => void | Fires when momentum scrolling ends | | onPositionReset | () => void | Fires when position resets during seamless loop | | onPause | () => void | Fires when carousel is paused | | onResume | () => void | Fires when carousel is resumed |

Callbacks are invoked with no specific this. For callback context and duplicated items/event listeners, see DOCS.md.

Methods

  • pause() - Pause automatic scrolling
  • resume() - Resume paused scrolling
  • destroy() - Clean up event listeners and reset the carousel

📖 For detailed API documentation, examples, and advanced usage, see DOCS.md

Examples

Basic Example

<div class="infinite-scroll-wrapper">
    <div class="infinite-scroll-container" id="myCarousel">
        <div class="infinite-scroll-item">Item 1</div>
        <div class="infinite-scroll-item">Item 2</div>
        <div class="infinite-scroll-item">Item 3</div>
        <div class="infinite-scroll-item">Item 4</div>
        <div class="infinite-scroll-item">Item 5</div>
    </div>
</div>

<script>
    const carousel = new InfiniteScrollCarousel('#myCarousel', {
        speed: 50,
        pauseOnHover: true
    });
</script>

Custom Configuration

<div class="infinite-scroll-wrapper">
    <div class="infinite-scroll-container" id="customCarousel">
        <div class="infinite-scroll-item">Item 1</div>
        <div class="infinite-scroll-item">Item 2</div>
        <div class="infinite-scroll-item">Item 3</div>
    </div>
</div>

<script>
    const carousel = new InfiniteScrollCarousel('#customCarousel', {
        speed: 40,
        reverseDirection: true,         // Scroll left to right
        fadeColor: '#1a1a2e',           // Custom fade color
        fadeWidth: 80,                  // Wider fade
        momentumDecay: 0.04,            // Smoother momentum
        copies: 5,                      // Cover gap with more copies
        onReady: () => {
            console.log('Carousel ready!');
        }
    });
</script>

📖 For more examples including React/Vue integration, advanced use cases, and styling guides, see DOCS.md

🌐 View interactive examples with code →

Browser Compatibility

✅ Chrome 64+, Firefox 69+, Safari 13.1+, Edge 79+
✅ Mobile support (iOS Safari 13.1+, Android Chrome 64+)
Requires: requestAnimationFrame, CSS transform, addEventListener (ResizeObserver has fallback support)

Troubleshooting

Items not scrolling? Ensure CSS is loaded and container has direct children.
Drag not working? Check that interactable: true and no CSS is blocking pointer events.
Items too close? Add margin: .infinite-scroll-item { margin-right: 30px; }
Speed issues? Adjust the speed option (set to 0 to disable auto-scroll).
Visible gap at end of items? The carousel runs out of duplicated copies to fill the infinite loop. Increase the copies option to add more item duplicates (default: 3).

📖 For detailed troubleshooting, styling guides, framework integration, and more examples, see DOCS.md

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for a list of changes and version history.

Support & Contributing

Contributions are welcome! Please feel free to submit a Pull Request.
For bug reports or feature requests, please open an issue on the repository.