react-swipe, react-swipeable, and react-swipeable-views all enable touch gesture support in React apps, but they serve different architectural needs and maintenance stages. react-swipeable-views provides a high-level carousel component but is officially deprecated and no longer maintained. react-swipe is a legacy wrapper around vanilla JavaScript swipe logic, often lacking modern React patterns. react-swipeable offers a modern, hook-based approach for building custom swipe interactions, giving developers full control over gesture logic without locking them into a specific UI component.
When adding touch gestures to a React application, you typically need to detect swipes, handle direction, and manage state. The packages react-swipe, react-swipeable, and react-swipeable-views all address this, but they operate at different levels of abstraction and maintenance status. Let's compare how they handle gesture detection, component structure, and long-term viability.
The core difference lies in what they give you: raw gesture logic, a UI component, or a legacy wrapper.
react-swipeable provides a custom hook.
// react-swipeable: Hook-based logic
import { useSwipeable } from 'react-swipeable';
function Card() {
const handlers = useSwipeable({
onSwipedLeft: () => console.log('Swiped Left'),
onSwipedRight: () => console.log('Swiped Right'),
});
return <div {...handlers}>Swipe me</div>;
}
react-swipeable-views provides a pre-built carousel component.
// react-swipeable-views: Component-based (Legacy)
import SwipeableViews from 'react-swipeable-views';
function Carousel() {
return (
<SwipeableViews>
<div>View 1</div>
<div>View 2</div>
<div>View 3</div>
</SwipeableViews>
);
}
react-swipe wraps vanilla swipe logic in a React component.
// react-swipe: Wrapper Component
import Swipe from 'react-swipe';
function Slider() {
return (
<Swipe
onSwipe={(e, direction) => console.log(direction)}
swipeable={true}
>
<div>Slide 1</div>
<div>Slide 2</div>
</Swipe>
);
}
Choosing a library isn't just about features; it's about whether the library will survive the next React major version.
react-swipeable is actively maintained.
// react-swipeable: Modern React Support
// Works seamlessly with React 18 concurrent features
function App() {
const { onTouchStart, onTouchMove, onTouchEnd } = useSwipeable({
onSwiped: () => updateState()
});
// ... implementation
}
react-swipeable-views is archived.
// react-swipeable-views: Migration Warning
// ⚠️ Do not use in new projects
// Existing code should move to embla-carousel-react or similar
<SwipeableViews index={index} onChangeIndex={setIndex} />
react-swipe has minimal updates.
// react-swipe: Legacy Pattern
// ⚠️ Potential compatibility issues with React 18
<Swipe onSwipeLeft={handleLeft} onSwipeRight={handleRight}>
{/* Content */}
</Swipe>
How much control do you have over the look and feel of the swipe interaction?
react-swipeable gives 100% UI control.
// react-swipeable: Custom Styling
const handlers = useSwipeable({ onSwipedLeft: removeCard });
return (
<div
{...handlers}
className="custom-card-style"
style={{ transform: translateX }}
>
Content
</div>
);
react-swipeable-views enforces its own structure.
// react-swipeable-views: Limited Customization
<SwipeableViews
animationDuration={500}
slideStyle={{ transition: 'transform 0.5s' }}
>
{/* Slides */}
</SwipeableViews>
react-swipe offers moderate customization.
// react-swipe: Configurable Thresholds
<Swipe
swipeable={true}
tolerance={100}
onSwiping={(e) => console.log('Swiping...')}
>
{/* Content */}
</Swipe>
Efficient event handling is critical for smooth touch interactions on mobile devices.
react-swipeable optimizes event listeners.
preventDefault behavior explicitly.// react-swipeable: Passive Listeners
const handlers = useSwipeable({
onSwipedLeft: handleAction,
preventDefaultTouchmoveEvent: true, // Stop scroll while swiping
trackMouse: true // Support desktop testing
});
react-swipeable-views handles internals automatically.
// react-swipeable-views: Internal Handling
// Haptic feedback and resistance are built-in but opaque
<SwipeableViews
enableMouseEvents
resistance
>
{/* Slides */}
</SwipeableViews>
react-swipe binds events at the wrapper level.
// react-swipe: Standard Binding
<Swipe
onSwipingLeft={(e) => e.preventDefault()}
onSwiped={handleComplete}
>
{/* Content */}
</Swipe>
Despite their differences, all three aim to solve the same core problem: translating touch input into actions.
touchStart, touchMove, and touchEnd.// All packages abstract this math internally
// You get high-level callbacks like onSwipedLeft instead of raw coordinates
// All packages aim to prevent default browser navigation on swipe
// e.g., stopping back/forward history navigation on edge swipes
// Common config pattern across all
// threshold: 100, // pixels
// enabled: true
| Feature | react-swipeable | react-swipeable-views | react-swipe |
|---|---|---|---|
| Type | Hook (Logic) | Component (UI) | Component (Wrapper) |
| Maintenance | ✅ Active | ❌ Deprecated/Archived | ⚠️ Low Activity |
| Customization | 🔓 Full Control | 🔒 Limited | 🔓 Moderate |
| React Version | ✅ Modern (18+) | ⚠️ Legacy | ⚠️ Legacy |
| Best For | Custom Gestures | Quick Carousels (Old) | Legacy Support |
react-swipeable is the clear winner for modern development. It separates gesture logic from UI, allowing you to build accessible, custom interactions that fit your design system. It is the only choice for new projects requiring swipe logic.
react-swipeable-views served a purpose in the past for quick Material Design carousels, but its deprecation makes it a liability. Using it today introduces technical debt immediately.
react-swipe remains an option only for keeping old apps running. It lacks the flexibility and modern patterns needed for today's React ecosystem.
Final Thought: For touch interactions, prioritize logic over pre-built UI. Use react-swipeable to handle the input, and build the visual feedback yourself. This ensures your app remains maintainable and performant as React evolves.
Choose react-swipeable for new projects that require custom gesture handling without the overhead of a full carousel component. It provides a lightweight hook (useSwipeable) that integrates cleanly with functional components and allows you to build your own UI logic. This is the best choice for flexibility and long-term maintenance.
Choose react-swipe only if you are maintaining a legacy codebase that already depends on it and migration is not feasible. It wraps older vanilla JavaScript logic and does not align with modern React patterns like hooks. For any new development, avoid this package in favor of more maintained solutions.
Do NOT choose react-swipeable-views for new projects as it is officially deprecated and archived. While it offers a ready-made carousel interface, it lacks support for modern React versions and receives no security or feature updates. Migrate existing implementations to react-swipeable or dedicated carousel libraries like embla-carousel-react.
React swipe event handler hook
Visit the Docs site for information on usage, api, and demos.
Please see our contributions guide.
Active: Formidable is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.