noUiSlider
A lightweight, accessible JavaScript range slider with multi-touch support and zero dependencies.
Repository Health
Technical Analysis
noUiSlider is a vanilla JavaScript range slider library for building draggable single- and multi-handle sliders in web UIs. It ships as a single TypeScript-authored module compiled to CommonJS and ESM bundles, has zero runtime dependencies, and works across all modern browsers plus IE9+. It supports non-linear scales, RTL layouts, and vertical orientation out of the box.
Beyond basic dragging, it provides built-in keyboard and ARIA accessibility, multi-touch gestures on mobile devices, configurable pips (tick marks) and tooltips, value formatting/parsing hooks, and a small pub-sub event API for reading and writing slider state. Because it has no framework dependency, it is commonly wrapped by React, Vue, and Angular components, or used directly in vanilla JS/jQuery projects.
What You Get
- Single and multi-handle range sliders with drag, keyboard, and tap-to-move interaction
- Built-in ARIA roles and keyboard support for accessible sliders out of the box
- Configurable pips (tick marks), tooltips, and value formatting/parsing hooks
- TypeScript type definitions alongside CommonJS and ES module builds
- Support for non-linear step ranges, RTL layouts, and vertical orientation
Common Use Cases
- Price range filters on e-commerce and marketplace search pages
- Volume, brightness, or other analog-style controls in web apps
- Multi-handle sliders for scheduling or duration selection UIs
- Data visualization controls for filtering charts by numeric range
Under The Hood
Architecture
The entire library lives in a single TypeScript module (src/nouislider.ts, ~3,200 lines) organized into commented regions rather than separate files. Public entry points create/initialize validate the target element and options via testOptions(), then call an internal scope() factory that builds the slider’s runtime state (handles, connect bars, pips, tooltips) as closures over the DOM elements, returning a plain API object (set, get, on, off, updateOptions, destroy, pips, and more). There are no classes or instances in the conventional sense — each slider’s state is captured entirely in the closure created per create() call, so anything touching that closure (event binding, position math) has to be traced through the single scope() function rather than across discrete modules.
Tech Stack
Written in TypeScript (^4.5) with its own hand-authored interfaces for options, formatters, pips, and the public API surface. Built with Rollup (rollup-plugin-typescript2) for the ESM/CJS bundles and tsc for type declarations, then minified with uglify-js; styles are authored in Less (nouislider.less plus modular partials) and compiled with lessc/less-plugin-clean-css. package.json declares zero runtime dependencies, keeping the shipped bundle self-contained. Linting uses ESLint with @typescript-eslint, formatting via Prettier.
Code Quality
Tests live under tests/ as ~30 QUnit-style browser test files (slider_*.js) exercising behaviors like RTL, keyboard interaction, pips, and option updates, run through an HTML harness (tests/slider.html) that loads QUnit and Blanket.js for coverage in a real browser — there is no npm test script and no CI workflow wired to run them automatically (the only GitHub Actions workflow present handles closed-issue locking), so verification is manual rather than continuous. The source itself is comprehensively commented (roughly 13% comment-to-code ratio) and organized into named regions, with consistent camelCase naming and full type coverage through its own interfaces.
API Design
The public API is small and consistent: create(target, options) returns an object exposing get/set for values, on/off for a pub-sub event model, and updateOptions/destroy for lifecycle management, with sensible defaults so a working slider needs only a range and start option. Documentation is extensive — a dedicated reference site covers every option, event, and configuration pattern with runnable examples — which lowers the ramp-up cost for a library with a fairly large total option surface.