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

@jomurgel/native-scroll-slider

v0.0.7

Published

A simple slider that leverages native overflow scroll behavior.

Readme

Native Scroll Slider

A lightweight, dependency-free JavaScript slider that leverages native browser scrolling for smooth, performant carousel experiences. Built with modern web standards and optimized for minimal bundle size.

npm version Bundle Size License: MIT

✨ Features

  • Ultra-lightweight: Only ~3.7KB (~0.5KB gzipped) - 90% smaller than alternatives
  • Native performance: Uses browser's native scrolling for 60fps animations
  • Touch-friendly: Built-in touch/swipe support without additional libraries
  • Native scrolling: Touch and mouse drag scrolling work naturally - no hijacked events
  • Highly configurable: 20+ options for complete customization
  • Responsive: Built-in responsive breakpoints and adaptive layouts
  • Accessible: Keyboard navigation and screen reader friendly
  • Multiple modes: Standard, infinite scroll, bounce-back, and center mode
  • Zero dependencies: Pure vanilla JavaScript, works everywhere
  • Modern browsers: ES6+ with graceful degradation

📦 Installation

npm

npm install @jomurgel/native-scroll-slider

CDN (Coming Soon)

<script src="https://unpkg.com/@jomurgel/native-scroll-slider/dist/native-scroll-slider.min.js"></script>
<script>
  const slider = new NativeScrollSlider(document.querySelector('.slider-track'));
</script>

NPM Imports

import NativeScrollSlider from '@jomurgel/native-scroll-slider';
// or
import NativeScrollSlider from 'native-scroll-slider';

Direct Download

Download from GitHub releases

🚀 Quick Start

Basic HTML Structure

<div class="slider-container" data-slider-config='{"slidesToShow": 3, "autoplay": true}'>
  <div class="slider-track">
    <div class="slide">Slide 1</div>
    <div class="slide">Slide 2</div>
    <div class="slide">Slide 3</div>
    <div class="slide">Slide 4</div>
    <div class="slide">Slide 5</div>
  </div>
  <button class="slider-prev">Previous</button>
  <button class="slider-next">Next</button>
</div>

JavaScript Initialization

import NativeScrollSlider from '@jomurgel/native-scroll-slider';

// Initialize with default options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'));

// Or with custom options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'), {
  slidesToShow: 3,
  autoplay: true,
  autoplaySpeed: 4000,
  infinite: true,
  responsive: [
    {
      breakpoint: 768,
      settings: {
        slidesToShow: 1
      }
    }
  ]
});

⚙️ Configuration Options

Complete Options Table

| Option | Type | Default | Description | |--------|------|---------|-------------| | slidesToShow | number | 4 | Number of slides visible at once | | slidesToScroll | number | 1 | Number of slides to scroll at once | | infinite | boolean | false | Enable infinite scrolling | | bounceBack | boolean | false | Enable bounce-back at edges | | centerMode | boolean | false | Center the active slide | | autoplay | boolean | false | Enable automatic sliding | | autoplaySpeed | number | 3000 | Autoplay interval in milliseconds | | gap | number | 24 | Gap between slides in pixels | | startSlide | number | 0 | Index of initial slide | | responsive | array | [...] | Responsive breakpoint settings (see below) | | prevElement | string | '.prev, .slider-prev, .slider-grid-prev' | Previous button selector | | nextElement | string | '.next, .slider-next, .slider-grid-next' | Next button selector | | minSlideWidth | number | 0 | Minimum slide width in pixels | | showOverflow | boolean | false | Show partial next/previous slides + enable full-width mode | | overflowAmount | number | 0.5 | Amount of overflow slide to show (0-1) | | containerMaxWidth | number | 1200 | Max container width for overflow mode | | basePadding | number | 35 | Base padding for overflow mode |

Default Responsive Breakpoints

The slider includes these responsive breakpoints by default:

responsive: [
  {
    breakpoint: 1200,
    settings: { slidesToShow: 3 }
  },
  {
    breakpoint: 992,
    settings: { slidesToShow: 2 }
  },
  {
    breakpoint: 768,
    settings: { slidesToShow: 1 }
  },
  {
    breakpoint: 576,
    settings: { slidesToShow: 1 }
  }
]

Configuration Methods

1. JavaScript Options

const slider = new NativeScrollSlider(track, {
  slidesToShow: 3,
  autoplay: true,
  infinite: true
});

2. Data Attributes

<div data-slider-config='{"slidesToShow": 2, "autoplay": true}'>
  <div class="slider-track">...</div>
</div>

3. Responsive Configuration

const slider = new NativeScrollSlider(track, {
  slidesToShow: 4, // Desktop default
  responsive: [
    {
      breakpoint: 1200,
      settings: {
        slidesToShow: 3
      }
    },
    {
      breakpoint: 992,
      settings: {
        slidesToShow: 2
      }
    },
    {
      breakpoint: 768,
      settings: {
        slidesToShow: 1,
        centerMode: true
      }
    },
    {
      breakpoint: 576,
      settings: {
        slidesToShow: 1,
        autoplay: false
      }
    }
  ]
});

🎯 Usage Examples

Image Gallery

<div class="gallery-slider">
  <div class="slider-track">
    <div class="slide"><img src="image1.jpg" alt="Image 1"></div>
    <div class="slide"><img src="image2.jpg" alt="Image 2"></div>
    <div class="slide"><img src="image3.jpg" alt="Image 3"></div>
  </div>
</div>

<script>
new NativeScrollSlider(document.querySelector('.gallery-slider .slider-track'), {
  slidesToShow: 1,
  infinite: true,
  autoplay: true,
  centerMode: true
});
</script>

Product Carousel

<div class="product-carousel" data-slider-config='{"slidesToShow": 4, "showOverflow": true}'>
  <div class="slider-track">
    <div class="slide product-card">Product 1</div>
    <div class="slide product-card">Product 2</div>
    <div class="slide product-card">Product 3</div>
    <div class="slide product-card">Product 4</div>
    <div class="slide product-card">Product 5</div>
  </div>
  <button class="slider-prev">←</button>
  <button class="slider-next">→</button>
</div>

Hero Banner Slider

const heroSlider = new NativeScrollSlider(document.querySelector('.hero-track'), {
  slidesToShow: 1,
  autoplay: true,
  autoplaySpeed: 5000,
  infinite: true,
  showOverflow: true, // Enables full-width breakout
  responsive: [
    {
      breakpoint: 768,
      settings: {
        showOverflow: false
      }
    }
  ]
});

Card Deck with Overflow

const cardSlider = new NativeScrollSlider(document.querySelector('.cards-track'), {
  slidesToShow: 3,
  showOverflow: true,
  overflowAmount: 0.3,
  gap: 20,
  responsive: [
    {
      breakpoint: 768,
      settings: {
        slidesToShow: 1,
        showOverflow: false
      }
    }
  ]
});

🎨 Styling

Basic CSS

.slider-container {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
}

.slider-track {
  display: flex;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.slider-track::-webkit-scrollbar {
  display: none;
}

.slide {
  flex-shrink: 0;
  scroll-snap-align: start;
}

/* Navigation buttons */
.slider-prev,
.slider-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  background: rgba(0,0,0,0.5);
  color: white;
  border: none;
  padding: 10px;
  cursor: pointer;
}

.slider-prev {
  left: 10px;
}

.slider-next {
  right: 10px;
}

.slider-prev:disabled,
.slider-next:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

Center Mode Styling

.slide {
  transition: transform 0.3s ease, opacity 0.3s ease;
  opacity: 0.6;
  transform: scale(0.8);
}

.slide.center {
  opacity: 1;
  transform: scale(1);
}

📱 Responsive Design

Mobile-First Approach

const responsiveSlider = new NativeScrollSlider(track, {
  // Mobile defaults (matches built-in responsive)
  slidesToShow: 4, // Desktop default
  
  // Custom responsive overrides (combines with defaults)
  responsive: [
    {
      breakpoint: 1200,
      settings: {
        slidesToShow: 3,
        gap: 20
      }
    },
    {
      breakpoint: 992,
      settings: {
        slidesToShow: 2,
        gap: 16
      }
    },
    {
      breakpoint: 768,
      settings: {
        slidesToShow: 1,
        centerMode: true,
        gap: 12
      }
    }
  ]
});

🔧 API Reference

Creating a Slider Instance

// Store the slider instance to access methods
const slider = new NativeScrollSlider(document.querySelector('.slider-track'));

// Or with options
const slider = new NativeScrollSlider(document.querySelector('.slider-track'), {
  slidesToShow: 3,
  autoplay: true
});

Public Methods

// Navigation
slider.next();           // Go to next slide(s)
slider.prev();           // Go to previous slide(s)
slider.goToSlide(index); // Go to specific slide (0-based index)

// Lifecycle
slider.handleResize();   // Manually trigger resize recalculation
slider.destroy();        // Clean up event listeners and timers

Complete Example

// Create slider instance
const mySlider = new NativeScrollSlider(document.querySelector('.my-slider-track'), {
  slidesToShow: 3,
  autoplay: true,
  infinite: true
});

// Use the methods
document.querySelector('.custom-next-btn').addEventListener('click', () => {
  mySlider.next();
});

document.querySelector('.custom-prev-btn').addEventListener('click', () => {
  mySlider.prev();
});

// Go to specific slide
document.querySelector('.go-to-slide-3').addEventListener('click', () => {
  mySlider.goToSlide(2); // 0-based index, so 2 = 3rd slide
});

Public Properties

// Read-only access to slider state
slider.currentSlide;     // Current slide index (number)
slider.totalSlides;      // Total number of slides (number)
slider.track;            // Reference to track element (HTMLElement)
slider.container;        // Reference to container element (HTMLElement)
slider.isScrolling;      // Whether slider is currently scrolling (boolean)

Event Handling

// Listen to native scroll events on the track
const track = document.querySelector('.slider-track');

track.addEventListener('scroll', () => {
  console.log('Slider scrolled');
});

// Access slider state during scroll
slider.track.addEventListener('scroll', () => {
  console.log(`Current slide: ${slider.currentSlide}`);
  console.log(`Is scrolling: ${slider.isScrolling}`);
});

// Listen for scroll end (when user stops scrolling)
slider.track.addEventListener('scroll', () => {
  clearTimeout(slider.scrollEndTimer);
  slider.scrollEndTimer = setTimeout(() => {
    console.log('Scroll ended');
  }, 150);
});

Autoplay Control

Note: Autoplay is controlled internally through options. To control autoplay programmatically:

// Enable/disable via options
const slider = new NativeScrollSlider(track, {
  autoplay: true,
  autoplaySpeed: 3000
});

// Control through mouse events (built-in)
// Autoplay pauses on hover and resumes on leave automatically

// Manual control (access internal methods - use with caution)
slider.pauseAutoplay();  // Pause autoplay
slider.resumeAutoplay(); // Resume autoplay

🌟 Advanced Features

Infinite Scroll

const infiniteSlider = new NativeScrollSlider(track, {
  infinite: true,
  autoplay: true,
  slidesToShow: 3
});
// Automatically clones slides and manages seamless looping

Show Overflow Mode

const peekSlider = new NativeScrollSlider(track, {
  showOverflow: true,
  overflowAmount: 0.5, // Show 50% of next slide
  slidesToShow: 2
});
// Shows partial slides to indicate more content
// Also enables full-width breakout functionality

📊 Performance Comparison

| Library | Bundle Size (gzipped) | Dependencies | Performance | |---------|----------------------|--------------|-------------| | Native Scroll Slider | 0.5 KB | None | 60fps native | | Slick.js | 6.2 KB | jQuery | Good | | Swiper.js | 25 KB | None | Excellent | | Glide.js | 7 KB | None | Good | | Splide.js | 11 KB | None | Good |

Why Choose Native Scroll Slider?

  • Smallest footprint: 90% smaller than alternatives
  • Native performance: Leverages browser optimizations
  • Touch-first: Built-in mobile gestures with natural drag/swipe behavior
  • No hijacked scrolling: Touch and mouse events work as expected - just like any native scrolling container
  • Accessibility: Works with screen readers and keyboards
  • Future-proof: Uses web standards, not polyfills

🛠️ Browser Support

  • Modern browsers: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
  • Mobile: iOS 12+, Android 7+
  • Graceful degradation: Falls back to basic scrolling in older browsers

Feature Detection

// Check for required features
const isSupported = 'scrollBehavior' in document.documentElement.style;
if (isSupported) {
  new NativeScrollSlider(track, options);
} else {
  // Fallback or polyfill
}

🤝 Contributing

We welcome contributions! Here's how to get started:

Development Setup

# Clone the repository
git clone https://github.com/jomurgel/native-scroll-slider.git
cd native-scroll-slider

# Install dependencies
npm install

# Start development server
npm run dev

# Run tests
npm test

# Build for production
npm run build

Contribution Guidelines

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for new functionality
  4. Ensure all tests pass (npm test)
  5. Commit changes (git commit -m 'Add amazing feature')
  6. Push to branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Code Standards

  • Use ES6+ features
  • Follow existing code style
  • Add JSDoc comments for new methods
  • Maintain backward compatibility
  • Keep bundle size minimal

🐛 Issues & Support

Reporting Issues

When reporting issues, please include:

  • Browser and version
  • Device type (desktop/mobile)
  • Minimal reproduction case
  • Expected vs actual behavior
  • Console errors (if any)

Report issues: GitHub Issues

Common Issues

Q: Slider not initializing

// Ensure DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
  new NativeScrollSlider(document.querySelector('.slider-track'));
});

Q: Touch scrolling not working

/* Ensure proper touch-action */
.slider-track {
  touch-action: pan-x;
}

Q: Slides not sized correctly

// Call handleResize after dynamic content loads
slider.handleResize();

📄 License

MIT License © 2024 Jo Murgel - see LICENSE file for details.

🙏 Acknowledgments

  • Inspired by native browser scrolling capabilities
  • Built for modern web performance standards
  • Responsive breakpoints based on 2025 design playbook
  • Designed with accessibility in mind

📈 Changelog

v0.0.1

  • Initial release
  • Core sliding functionality with desktop-first defaults (4 slides).
  • Built-in responsive breakpoints (1200/992/768/576px).
  • Autoplay support with hover pause/resume.
  • Infinite scroll mode with dynamic clone management.
  • Center mode with visual highlighting.
  • Show overflow mode with full-width breakout capability.
  • Touch/swipe support via native scroll behavior.

v0.0.2

  • Cleanup and minor bugfixes.

v0.0.3

  • Fixes minWidth handling with centerMode active.

v0.0.4

-Improves infinite scroll behavior.

v0.0.5

  • Improves hanlding of next/previous buttons when the slider container width is variable.

v0.0.6

  • Fixes bug where nav buttons were being ignored when multiple sliders are present.

v0.0.7

  • Updates js structure. Takes proof of concept into more organized file strucutre.
  • Adds demo for Github Pages
  • Adds deployment updates for npm and GH pages.

Made with ❤️ by jomurgel

For more examples and documentation, visit: https://github.com/jomurgel/native-scroll-slider