Jesse A. Green / notebook

Swiper Admin & Architecture Guide

Generated June 2026 from nolimits4web/swiper at 929c014

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide is the technical reference for engineers, architects, and maintainers who integrate, extend, audit, or build on Swiper. It documents the library's architecture, its complete public API (every parameter, method, property, and event), the build and packaging system, its styling and CSS-class contract, security posture, and a roadmap of known issues and improvements.

It is the companion to the User Guide (everyday usage and recipes). Where the User Guide shows how to use Swiper, this guide explains how Swiper is built and gives the exhaustive reference tables.

Note

Reference target: Swiper v12.2.0 (package name swiper), MIT-licensed, authored by Vladimir Kharlampidi. Homepage: swiperjs.com. This document is derived directly from the TypeScript definitions and source.


1. Executive Summary

Swiper is a dependency-free, framework-agnostic touch slider for the web. Its defining engineering characteristics:

  • Modular & tree-shakeable. A small core handles layout, touch, and transitions; every feature (navigation, pagination, autoplay, effects, zoom, …) is an independently importable module. Unused modules never enter your bundle.
  • Multi-target distribution. One source produces six consumption surfaces: a core ES module, an all-in-one bundle, a React component set, a Vue component set, a Web Component (<swiper-container>), and per-module CSS.
  • No runtime dependencies. Swiper ships zero production dependencies. There is no server, no network I/O, no configuration files, and no secrets — it is a client-side UI library configured entirely by a JavaScript options object.
  • Type-first API. The authoritative API contract lives in TypeScript declaration files (.d.ts) whose JSDoc carries the description, type, default, and examples for every option, method, and event.
Attribute Value
Package swiper (v12.2.0)
License MIT
Module format ESM ("type": "module")
Runtime dependencies None
Install requirement Node.js >= 4.7.0 (build/install only)
Source layout All source under src/; build emits to dist/
Build tooling Rollup + Babel (JS), PostCSS/Less + clean-css/cssnano (CSS), custom Node build scripts
Targets Core, Bundle, React, Vue, Element (web component)

2. Architecture

2.1 High-level structure

                         ┌─────────────────────────────┐
                         │        Swiper core           │
                         │  (src/core/*)                │
                         │  layout · touch · transition │
                         │  translate · update · loop   │
                         └───────────────┬──────────────┘
                                         │ lifecycle events + extendParams()
        ┌────────────────────────────────┼────────────────────────────────┐
        │                                 │                                 │
 ┌──────┴───────┐                 ┌───────┴────────┐                ┌───────┴────────┐
 │  Feature      │                │   Effect        │                │  Integration   │
 │  modules      │                │   modules       │                │  wrappers      │
 │ (src/modules) │                │ (effect-*)      │                │ react/vue/     │
 │ navigation    │                │ fade/cube/flip  │                │ element        │
 │ pagination    │                │ coverflow/cards │                │                │
 │ autoplay …    │                │ creative        │                │                │
 └──────────────┘                 └────────────────┘                └────────────────┘

 dist/ build targets:
   swiper.mjs              core class
   swiper-bundle.mjs       core + all modules
   modules/index.mjs       individual modules (swiper/modules)
   swiper-react.mjs        React components
   swiper-vue.mjs          Vue components
   swiper-element.mjs      <swiper-container> web component
   *.css                   core + per-module styles

2.2 The core (src/core)

The core is responsible for everything that is not an optional feature. Its subfolders map directly to responsibilities (all scored HIGH in source triage):

Core folder Responsibility
src/core Constructor, parameter merging, init/destroy lifecycle
src/core/events Touch/pointer event binding (start/move/end), click handling
src/core/slide slideTo / slideNext / slidePrev / slideReset / slideToClosest logic
src/core/transition Transition start/end orchestration
src/core/translate Reading/setting the wrapper translate, min/max translate
src/core/update Size/slides/progress/classes recalculation
src/core/loop Loop slide creation/destruction and "loop fix"
src/core/breakpoints Resolving and applying responsive breakpoints
src/core/grab-cursor Grab-cursor desktop affordance
src/core/check-overflow watchOverflow locking when there aren't enough slides
src/core/classes Computing CSS classes for container and slides

2.3 The module system

A module is a function conforming to the SwiperModule type (from src/types/shared.d.ts):

export type SwiperModule = (options: {
  params: Swiper['params'];
  swiper: Swiper;
  extendParams: (obj: { [name: string]: any }) => void;
  on: Swiper['on'];
  once: Swiper['once'];
  off: Swiper['off'];
  emit: Swiper['emit'];
}) => void;

Each module receives the live instance and the event bus. It:

  1. Calls extendParams() to register its own option object and defaults (e.g. the navigation module registers the navigation option block).
  2. Subscribes to core lifecycle events (init, update, slideChange, setTranslate, resize, …) via on().
  3. Adds its own state/methods to the instance (e.g. swiper.navigation, swiper.autoplay) and emits its own events (navigationNext, autoplayStart, …).

Modules are installed either by passing them in the modules array per-instance, or globally with the static Swiper.use([...]). The bundle build pre-installs all of them.

Note

This is why the User Guide repeatedly frames a feature as "three pieces": the module import (JS), the modules array entry (installation), and the CSS import (styling). The architecture enforces that separation to keep the core tiny.

2.4 Integration wrappers

Wrapper Source What it adapts
React (src/react) swiper-react.d.ts <Swiper> / <SwiperSlide> components; props mirror SwiperOptions; events as on<Event> props; useSwiper()/useSwiperSlide() hooks
Vue (src/vue) swiper-vue.d.ts <swiper>/<swiper-slide> components; props mirror options; @event listeners; useSwiper()/useSwiperSlide() composables (reactive refs)
Element (src/swiper-element.d.ts) Web component <swiper-container>/<swiper-slide> custom elements; Shadow DOM; kebab-case attributes; register() entry
Shared (src/components-shared, src/shared) — Code shared across the React/Vue/Element wrappers (param parsing, slot handling, event wiring)

The wrappers are thin: they translate framework idioms (props, slots, reactivity) into the same core SwiperOptions object and instance the User Guide already documented. The React/Vue components additionally manage the instance lifecycle (init on mount, update on prop change, destroy on unmount).


3. Packaging & Distribution

3.1 The exports map (canonical entry points)

The published package's exports field (src/copy/package.json) is the authoritative list of import specifiers. Engineers should treat it as the contract — only these entry points are public.

Entry point types default
swiper / swiper/core swiper.d.ts swiper.mjs
swiper/bundle swiper.d.ts swiper-bundle.mjs
swiper/effect-utils swiper-effect-utils.d.ts swiper-effect-utils.mjs
swiper/modules types/modules/index.d.ts modules/index.mjs
swiper/react swiper-react.d.ts swiper-react.mjs
swiper/vue swiper-vue.d.ts swiper-vue.mjs
swiper/element swiper-element.d.ts swiper-element.mjs
swiper/element/bundle swiper-element.d.ts swiper-element-bundle.mjs
swiper/css / swiper/swiper.css swiper.css.d.ts swiper.css
swiper/css/bundle swiper-bundle.css.d.ts swiper-bundle.css
swiper/css/<module> modules/<module>.css.d.ts modules/<module>.css
swiper/element/css/<module> modules/<module>-element.css.d.ts modules/<module>-element.css
swiper/types types/index.d.ts —

Per-module CSS entry points exist for: a11y, autoplay, controller, effect-coverflow, effect-cube, effect-fade, effect-flip, effect-creative, effect-cards, free-mode, grid, hash-navigation, history, keyboard, manipulation, mousewheel, navigation, pagination, parallax, scrollbar, thumbs, virtual, zoom — and the same set again under swiper/element/css/* for the Shadow-DOM web component.

Important

The web component uses separate *-element.css files (suffixed -element) because Shadow-DOM-scoped styling differs from light-DOM styling. When using <swiper-container>, inject styles via the element's injectStyles/injectStylesUrls properties rather than importing global CSS.

3.2 Build pipeline

The build is driven by custom Node scripts (scripts/), orchestrated through npm scripts in the root package.json:

Command Purpose
npm run build Development build → dist/
npm run build:prod Production build → dist/
npm run watch Rebuild on source change
npm run core / react / vue / element Build + serve the matching playground via Vite
npm run demos Build + serve the demos/ site
npm run lint ESLint (airbnb-base + prettier)
npm run check-format / format Prettier check / write
npm run validate check-format + lint in parallel
npm test validate then build:prod
npm run release validate then the release script
npm run build-icons-font Generate the icon font (Python script)
npm run changelog Conventional-changelog (Angular preset)

Toolchain (from devDependencies): Rollup (rollup, @rollup/plugin-babel, @rollup/plugin-node-resolve, @rollup/plugin-replace) for JS bundling; Babel (@babel/core, preset-env, preset-react) for transpilation; PostCSS (postcss, postcss-nested, autoprefixer, cssnano) and Less (less) plus clean-css for styles; terser for minification; Vite for the playgrounds.

Note

Per the README's contribution rule, all changes go into src/ only — dist/ is generated. The dist/ folder is what consumers should use in production; src/ is the editable source of truth.

3.3 Build-time flags

The single build-time configuration value found in source is the environment variable SWIPER_BUILD_MODULES (read via process.env in scripts/utils/helper.js). It controls which modules the build script includes when assembling targets. It is a build concern only — it has no effect at runtime in the browser.

Note

Swiper has no runtime configuration files and no runtime environment variables. All runtime behavior is set through the SwiperOptions object passed to the constructor (documented in §4). There is no .env, no config schema, and no config loader to manage.


4. Complete Parameter Reference (SwiperOptions)

Every core parameter, its type, and its default — taken verbatim from src/types/swiper-options.d.ts. Module-specific option blocks are in §6.

4.1 Initialization & lifecycle

Parameter Type Default Description
modules SwiperModule[] — Modules to install on this instance
init boolean true Auto-initialize on construction; if false, call swiper.init() manually
enabled boolean true Whether Swiper starts enabled (disabled hides nav and ignores interaction)
runCallbacksOnInit boolean true Fire transition/slideChange events during init (when initialSlide ≠ 0 or loop)
initialSlide number 0 Index of the slide shown initially
direction 'horizontal' | 'vertical' 'horizontal' Slide axis
speed number 300 Transition duration (ms)
updateOnWindowResize boolean true Recalculate on window resize/orientationchange
resizeObserver boolean true Use ResizeObserver on the container when available
userAgent string | null null UA string for SSR device detection
url string | null null URL for SSR active-slide detection with history

4.2 Slides grid & sizing

Parameter Type Default Description
slidesPerView number | 'auto' 1 Slides visible at once
slidesPerGroup number 1 Slides advanced per action
slidesPerGroupSkip number 0 First N slides treated as single groups
slidesPerGroupAuto boolean false With slidesPerView:'auto', skip all in-view slides per action
spaceBetween number | string 0 Gap between slides (px)
centeredSlides boolean false Center the active slide
centeredSlidesBounds boolean false Center without gaps at the edges (needs centeredSlides)
slidesOffsetBefore number 0 Extra offset before the first slide (px)
slidesOffsetAfter number 0 Extra offset after the last slide (px)
normalizeSlideIndex boolean true Normalize the active slide index
centerInsufficientSlides boolean false Center when fewer slides than slidesPerView
snapToSlideEdge boolean false Always snap to slide edges (fractional/'auto' only)
setWrapperSize boolean false Set explicit wrapper size (flexbox fallback)
autoHeight boolean false Container height follows the active slide
roundLengths boolean false Round slide sizes (avoid blurry text)
width number | null null Force width (disables responsiveness)
height number | null null Force height (disables responsiveness)
maxBackfaceHiddenSlides number 10 Threshold for backface-visibility:hidden (Safari flicker fix)

4.3 Touch, swipe & resistance

Parameter Type Default Description
grabCursor boolean false Show grab cursor on hover
touchEventsTarget 'container' | 'wrapper' 'wrapper' Element to listen for touch on
touchRatio number 1 Touch movement ratio
touchAngle number 45 Angle (deg) to trigger a touch move
simulateTouch boolean true Accept mouse as touch (click-drag)
shortSwipes boolean true Enable short swipes
longSwipes boolean true Enable long swipes
longSwipesRatio number 0.5 Threshold ratio for long swipes
longSwipesMs number 300 Min duration (ms) for long swipes
followFinger boolean true Track finger during drag (vs. animate on release)
allowTouchMove boolean true Allow drag-to-slide
threshold number 5 Min touch distance (px) before moving
touchStartPreventDefault boolean true preventDefault on pointerdown
touchStartForcePreventDefault boolean false Always preventDefault on touchstart
touchMoveStopPropagation boolean false Stop propagation of touchmove
edgeSwipeDetection boolean | string false Release events for in-app swipe-back ('prevent' to block system)
edgeSwipeThreshold number 20 Edge area (px) for swipe-back
touchReleaseOnEdges boolean false Release touch at edges to allow page scroll (needs threshold:0)
passiveListeners boolean true Use passive listeners where possible
resistance boolean true Resistant bounds
resistanceRatio number 0.85 Resistance ratio
preventInteractionOnTransition boolean false Block slide change during transition
allowSlidePrev boolean true Allow sliding backward
allowSlideNext boolean true Allow sliding forward

4.4 Swiping behavior & clicks

Parameter Type Default Description
noSwiping boolean true Disable swiping on noSwipingClass elements
noSwipingClass string 'swiper-no-swiping' Class that disables swiping
noSwipingSelector string — Selector to disable swiping on (e.g. 'input')
swipeHandler CSSSelector | HTMLElement | null null Restrict swiping to this handle
preventClicks boolean true Prevent accidental clicks during swipe
preventClicksPropagation boolean true Stop click propagation during swipe
slideToClickedSlide boolean false Clicking a slide transitions to it
focusableElements string 'input, select, option, textarea, button, video, label' Elements where swiping is disabled when focused
uniqueNavElements boolean true Resolve nav/pagination/scrollbar selectors within children first

4.5 Progress, loop & rewind

Parameter Type Default Description
watchSlidesProgress boolean false Compute each slide's progress/visibility (adds visible class)
loop boolean false Continuous loop mode
loopAddBlankSlides boolean true Auto-add blank slides for grid/group evenness in loop
loopAdditionalSlides number 0 Increase number of looped slides
loopPreventsSliding boolean true Ignore slideNext/Prev while animating in loop
rewind boolean false Rewind at edges (don't combine with loop)

4.6 Effects (selector + per-effect blocks)

Parameter Type Default Description
effect 'slide' | 'fade' | 'cube' | 'coverflow' | 'flip' | 'creative' | 'cards' | string 'slide' Active transition effect
virtualTranslate boolean false Operate without setting real translate (custom transitions)
cssMode boolean false Use native CSS Scroll Snap (see note below)

Warning

cssMode: true swaps Swiper's JS-driven movement for the browser's CSS Scroll Snap. It can be much faster for simple sliders but does not support: Cube effect; the speed parameter may have no effect; transition start/end events (use slideChange); limited slidesPerGroup; simulateTouch/mouse-drag; resistance; allowSlidePrev/Next; and swipeHandler. With 3D effects you must wrap slide content in <div class="swiper-slide-transform">.

The per-effect option objects (fadeEffect, cubeEffect, coverflowEffect, flipEffect, cardsEffect, creativeEffect) are fully documented in §6.

4.7 Responsive & observation

Parameter Type Default Description
breakpoints { [width:number]: SwiperOptions; [ratio:string]: SwiperOptions } — Per-breakpoint parameter overrides (layout params only)
breakpointsBase 'window' | 'container' | CSSSelector 'window' Basis for breakpoint keys
observer boolean false MutationObserver on swiper + elements
observeParents boolean false Also observe parent elements
observeSlideChildren boolean false Also observe slide children
watchOverflow boolean true Lock/disable when there aren't enough slides

4.8 Element / Web Component parameters

Parameter Type Default Description
createElements boolean false Auto-create wrapper/nav/pagination/scrollbar elements
eventsPrefix string 'swiper' Prefix for DOM events emitted by <swiper-container>
swiperElementNodeName string 'SWIPER-CONTAINER' Node name used to detect web-component rendering
injectStyles string[] — Inline styles injected into the Shadow DOM
injectStylesUrls string[] — Stylesheet <link>s injected into the Shadow DOM

4.9 CSS class-name parameters (namespacing)

Each of these overrides a default Swiper CSS class. Defaults shown; changing them requires matching CSS changes. (Marked * are not supported in the React/Vue components.)

Parameter Default
containerModifierClass 'swiper-'
slideClass * 'swiper-slide'
slideActiveClass * 'swiper-slide-active'
slideVisibleClass * 'swiper-slide-visible'
slideFullyVisibleClass * 'swiper-slide-fully-visible'
slideNextClass * 'swiper-slide-next'
slidePrevClass * 'swiper-slide-prev'
slideBlankClass * 'swiper-slide-blank'
wrapperClass * 'swiper-wrapper'
lazyPreloaderClass 'swiper-lazy-preloader'
lazyPreloadPrevNext 0

4.10 Event registration parameters

Parameter Type Description
on { [event]: handler } Register event handlers at init (see §5 for the event list)
onAny (handler) => void Catch-all handler invoked for every event

Note

Negative knowledge The following do not exist as core options and should never be documented as such: there is no lazy core option (lazy loading is handled via lazyPreloadPrevNext + the swiper-lazy-preloader element and per-slide markup), no autoplay core boolean independent of the Autoplay module, and no top-level navigation/pagination/scrollbar behavior without importing the matching module. The only build-time variable is SWIPER_BUILD_MODULES; there are no runtime env vars.


5. Complete Events Reference

Core events from src/types/swiper-events.d.ts. Handlers receive the swiper instance as the first argument (plus any listed extras). Register via the on option, swiper.on(name, handler), .once(), or .off().

5.1 Lifecycle events

Event Extra args Fires
beforeInit — Right before init
init — After init (with swiper.on('init'), only when init:false)
afterInit — Right after init
beforeDestroy — Before destroy
destroy — On destroy
update — After swiper.update()

5.2 Slide-change events

Event Fires
slideChange Active slide changed
beforeSlideChangeStart Before slide-change starts
slideChangeTransitionStart / slideChangeTransitionEnd Slide-change animation start / end
slideNextTransitionStart / slideNextTransitionEnd Forward-direction only
slidePrevTransitionStart / slidePrevTransitionEnd Backward-direction only
slideResetTransitionStart / slideResetTransitionEnd Reset-to-current animation start / end
activeIndexChange activeIndex changed
snapIndexChange snapIndex changed
realIndexChange realIndex changed (loop)

5.3 Transition & translate events

Event Extra args Fires
beforeTransitionStart speed, internal Before a transition starts
transitionStart / transitionEnd — Transition start / end
setTranslate translate Wrapper position changed
setTransition transition Animation duration set
momentumBounce — Momentum bounce occurred

5.4 Pointer / interaction events

Each receives (swiper, event) where event is a MouseEvent \| TouchEvent \| PointerEvent (except sliderFirstMove, which receives a TouchEvent):

touchStart, touchMove, touchMoveOpposite, sliderMove, sliderFirstMove, touchEnd, click, tap, doubleTap, doubleClick.

5.5 Position / edge events

Event Extra args Fires
progress progress (0–1) Progress changed
reachBeginning — Reached the first slide
reachEnd — Reached the last slide
toEdge — Moved to an edge
fromEdge — Moved away from an edge
lock / unlock — Locked / unlocked (via watchOverflow)

5.6 Layout / structural events

Event Extra args Fires
slidesUpdated — Slides + sizes recalculated
slidesLengthChange — Number of slides changed
slidesGridLengthChange — Slides grid changed
snapGridLengthChange — Snap grid changed
resize / beforeResize — On resize handling
orientationchange — Device orientation changed
observerUpdate — Observer detected DOM mutation
breakpoint breakpointParams Breakpoint changed
beforeLoopFix / loopFix — Around loop rearrangement
changeDirection — Direction changed

Note

Events prefixed with _ (e.g. _beforeBreakpoint, _containerClasses, _slideClass, _swiper, _freeModeNoMomentumRelease) are internal. They are emitted for internal/integration plumbing and are not part of the stable public API — do not rely on them.

Module events (e.g. autoplayStart, navigationNext, paginationRender, zoomChange, hashChange, scrollbarDragMove, keyPress, scroll) are listed with their modules in §6.


6. Module Reference

For each module: its option object (with defaults), the instance methods it adds, and the events it emits. Source: src/types/modules/*.d.ts.

6.1 Navigation

Options: enabled?, nextEl/prevEl (null), addIcons (true), hideOnClick (false), disabledClass ('swiper-button-disabled'), hiddenClass ('swiper-button-hidden'), lockClass ('swiper-button-lock'), navigationDisabledClass ('swiper-navigation-disabled'). Instance (swiper.navigation): nextEl, prevEl, update(), init(), destroy(). Events: navigationShow, navigationHide, navigationPrev, navigationNext.

6.2 Pagination

Options: enabled?, el (null), type ('bullets'), bulletElement ('span'), dynamicBullets (false), dynamicMainBullets (1), hideOnClick (true), clickable (false), progressbarOpposite (false), render hooks renderBullet/renderFraction/renderProgressbar/renderCustom, formatFractionCurrent/formatFractionTotal, plus class names: bulletClass ('swiper-pagination-bullet'), bulletActiveClass ('swiper-pagination-bullet-active'), modifierClass ('swiper-pagination-'), currentClass, totalClass, hiddenClass, progressbarFillClass, progressbarOppositeClass, clickableClass, lockClass, horizontalClass, verticalClass, paginationDisabledClass. Instance (swiper.pagination): el, bullets[], render(), update(), init(), destroy(). Events: paginationRender, paginationUpdate, paginationShow, paginationHide.

6.3 Scrollbar

Options: enabled?, el (null), hide (true), draggable (false), snapOnRelease (false), dragSize ('auto'), lockClass ('swiper-scrollbar-lock'), dragClass ('swiper-scrollbar-drag'), scrollbarDisabledClass, horizontalClass, verticalClass. Instance (swiper.scrollbar): el, dragEl, updateSize(), setTranslate(), init(), destroy(). Events: scrollbarDragStart, scrollbarDragMove, scrollbarDragEnd (each receives the pointer event).

6.4 Autoplay

Options: delay (3000), stopOnLastSlide (false), disableOnInteraction (true), reverseDirection (false), waitForTransition (true), pauseOnMouseEnter (false). Instance (swiper.autoplay): running, paused, timeLeft, start(), stop(), pause(), resume(). Events: autoplayStart, autoplayStop, autoplayPause, autoplayResume, autoplay, autoplayTimeLeft(swiper, timeLeft, percentage). Per-slide override: data-swiper-autoplay="<ms>".

6.5 Keyboard

Options: enabled (false), onlyInViewport (true), pageUpDown (true), speed. Instance (swiper.keyboard): enabled, enable(), disable(). Events: keyPress(swiper, keyCode).

6.6 Mousewheel

Options: enabled (false), forceToAxis (false), releaseOnEdges (false), invert (false), sensitivity (1), eventsTarget ('container'), thresholdDelta (null), thresholdTime (null), noMousewheelClass ('swiper-no-mousewheel'). Instance (swiper.mousewheel): enabled, enable(), disable(). Events: scroll(swiper, WheelEvent).

6.7 Zoom

Options: limitToOriginalSize (false), maxRatio (3), minRatio (1), panOnMouseMove (false), toggle (true), containerClass ('swiper-zoom-container'), zoomedSlideClass ('swiper-slide-zoomed'). Instance (swiper.zoom): enabled, scale, enable(), disable(), in(ratio?), out(), toggle(event?). Events: zoomChange(swiper, scale, imageEl, slideEl).

6.8 Thumbs

Options: swiper (null — a Swiper instance, selector, or params), slideThumbActiveClass ('swiper-slide-thumb-active'), thumbsContainerClass ('swiper-thumbs'), multipleActiveThumbs (true), autoScrollOffset (0). Instance (swiper.thumbs): swiper, update(initial, p?), init().

6.9 Virtual

Options: enabled (false), slides ([]), slidesPerViewAutoSlideSize (320), cache (true), addSlidesBefore (0), addSlidesAfter (0), renderSlide (null), renderExternal (null), renderExternalUpdate (true). Instance (swiper.virtual): cache, from, to, slides[], appendSlide(), prependSlide(), removeSlide(), removeAllSlides(), update(force).

6.10 Free Mode

Options: enabled (false), momentum (true), momentumRatio (1), momentumVelocityRatio (1), momentumBounce (true), momentumBounceRatio (1), minimumVelocity (0.02), sticky (false). Instance (swiper.freeMode): onTouchMove(), onTouchEnd().

6.11 Grid

Options: rows (1), fill ('column' — 'row' or 'column').

6.12 Controller

Options: control (Swiper instance(s), selector, or element — null), inverse (false), by ('slide' — 'slide' or 'container'). Instance (swiper.controller): control.

6.13 A11y

Options (enabled by default): enabled (true), prevSlideMessage ('Previous slide'), nextSlideMessage ('Next slide'), firstSlideMessage ('This is the first slide'), lastSlideMessage ('This is the last slide'), paginationBulletMessage ('Go to slide {{index}}'), notificationClass ('swiper-notification'), containerMessage (null), containerRoleDescriptionMessage (null), containerRole (null), itemRoleDescriptionMessage (null), slideLabelMessage ('{{index}} / {{slidesLength}}'), slideRole ('group'), id (null), scrollOnFocus (true), wrapperLiveRegion (true). Placeholders: {{index}}, {{slidesLength}}.

6.14 Hash Navigation

Options: watchState (false), replaceState (false), getSlideIndex(swiper, hash) (for virtual slides). Events: hashChange, hashSet.

6.15 History

Options: enabled (false), root (''), replaceState (false), key ('slides'), keepQuery (false). Per-slide URL segment via data-history="<value>".

6.16 Parallax

Options: enabled (false). Parallaxed elements inside slides use data-swiper-parallax* attributes.

6.17 Manipulation (core only)

Adds slide-editing methods to the instance: appendSlide(), prependSlide(), addSlide(index, slides), removeSlide(indexOrIndexes), removeAllSlides(). Accepts HTML strings or HTMLElement(s). In React/Vue, manipulate the data source instead.

6.18 Effect modules

Module Options (defaults)
EffectFade crossFade (false)
EffectCube slideShadows (true), shadow (true), shadowOffset (20), shadowScale (0.94)
EffectCoverflow slideShadows (true), rotate (50), stretch (0, number or %), depth (100), scale (1), modifier (1)
EffectFlip slideShadows (true), limitRotation (true)
EffectCards slideShadows (true), rotate (true), perSlideRotate (2), perSlideOffset (8)
EffectCreative prev/next transform objects, limitProgress (1), shadowPerProgress (false), progressMultiplier (1), perspective (true)

The EffectCreative prev/next transform shape: { translate?: (string|number)[]; rotate?: number[]; opacity?: number; scale?: number; shadow?: boolean; origin?: string }.


7. Instance API (Swiper class)

From src/types/swiper-class.d.ts.

7.1 Construction & statics

new Swiper(container: CSSSelector | HTMLElement, options?: SwiperOptions)
Static Purpose
Swiper.use(modules) Install modules globally
Swiper.defaults The default options object
Swiper.extendDefaults(options) Extend global defaults
Swiper.extendedDefaults Current global extended defaults

7.2 Navigation methods

Method Returns Purpose
slideNext(speed?, runCallbacks?) boolean Go to next slide
slidePrev(speed?, runCallbacks?) boolean Go to previous slide
slideTo(index, speed?, runCallbacks?) boolean Go to a specific index
slideToLoop(index, speed?, runCallbacks?) Swiper Go to a slide by real index (loop)
slideReset(speed?, runCallbacks?) boolean Reset to the active slide
slideToClosest(speed?, runCallbacks?) boolean Snap to the closest slide
setProgress(progress, speed?) void Set translate progress (0–1)

7.3 Update / layout methods

update(), updateSize(), updateSlides(), updateProgress(), updateSlidesClasses(), updateAutoHeight(speed?), slidesPerViewDynamic(), changeDirection(direction?, needUpdate?), changeLanguageDirection('rtl' | 'ltr').

7.4 Translate methods

setTranslate(value), getTranslate(), translateTo(translate, speed, runCallbacks?, translateBounds?), minTranslate(), maxTranslate(), setGrabCursor(), unsetGrabCursor().

7.5 Lifecycle & events methods

init(el?), destroy(deleteInstance?, cleanStyles?), enable(), disable(), attachEvents(), detachEvents(), on(event, handler), once(event, handler), off(event, handler?), emit(event, ...args), onAny(handler), offAny(handler).

7.6 Key instance properties (read state)

Property Type Meaning
params / originalParams SwiperOptions Effective / original options
el / wrapperEl / slidesEl HTMLElement Container / wrapper / slides container
slides HTMLElement[] Slide elements
width / height number Container size
translate number Current wrapper translate
progress number 0–1 progress
activeIndex number Active slide index (DOM order)
realIndex number Active slide real index (loop)
previousIndex / snapIndex number Previous active / current snap index
snapGrid / slidesGrid / slidesSizesGrid number[] Computed grids
isBeginning / isEnd boolean At first / last position
isLocked boolean Locked by watchOverflow
animating boolean In transition
swipeDirection 'prev' | 'next' Current swipe direction
touches { startX, startY, currentX, currentY, diff } Touch state
clickedIndex / clickedSlide number / HTMLElement Last clicked slide
allowSlideNext / allowSlidePrev / allowTouchMove boolean Writable gates
enabled boolean Instance enabled
Module namespaces object swiper.navigation, swiper.pagination, swiper.autoplay, swiper.zoom, swiper.thumbs, swiper.virtual, etc. (present when the module is installed)

Note

Properties documented !INTERNAL in the source (loopedSlides, rtlTranslate, currentBreakpoint, destroyed, modules, loopCreate(), loopDestroy(), isHorizontal(), getBreakpoint(), setBreakpoint()) are implementation details and not part of the supported public API.


8. Styling & CSS Contract

8.1 Required structure & default classes

<div class="swiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">...</div>
    <div class="swiper-slide">...</div>
  </div>
  <!-- optional module elements -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
  <div class="swiper-pagination"></div>
  <div class="swiper-scrollbar"></div>
</div>

Swiper computes state classes on slides at runtime: swiper-slide-active, swiper-slide-next, swiper-slide-prev, swiper-slide-visible, swiper-slide-fully-visible, swiper-slide-blank, swiper-slide-zoomed, and container modifier classes prefixed swiper- (direction, effect, RTL, locked, etc.). Module elements get their own state classes (e.g. swiper-button-disabled, swiper-pagination-bullet-active).

8.2 Light DOM vs Shadow DOM

Two parallel CSS sets exist:

  • Light DOM (swiper/css, swiper/css/<module>) — for the core/React/Vue usage where slides are in the normal document.
  • Shadow DOM (swiper/element/css/<module>, files suffixed -element) — for the <swiper-container> web component, whose internals are encapsulated. Inject these via injectStyles/injectStylesUrls.

Important

A recurring community request (issue #8164) asks Swiper to ship its built-in classes at 0 CSS specificity so apps can override them more easily. When theming, prefer overriding via the documented class-name parameters (§4.9) or layering your own classes rather than fighting specificity.


9. Security

Swiper is a client-side UI library: it has no server component, no network calls, no filesystem access, no credentials, and no environment-variable configuration. The attack surface is therefore limited to what runs in the user's browser when slides and options are rendered. Key considerations:

9.1 Known vulnerability class — prototype pollution

The project's issue tracker shows active security work in the prototype pollution class:

  • #8189 — "Incomplete Fix for CVE-2026-27212" (open): indicates a follow-up to a previously addressed CVE; the fix was reported as incomplete and is under review.
  • #8167 — "Can you backport the prototype pollution fix to v11?" (closed): a prototype-pollution fix landed and a backport to the v11 line was requested.

Implication for integrators:

Caution

Prototype-pollution issues in a slider typically arise when untrusted data is merged into the options object (deep-merge of attacker-controlled keys like __proto__). If you build Swiper options from user-supplied or third-party JSON, sanitize keys before passing them to new Swiper(...), and stay on the latest patched v12.x release. Track issue #8189 for the current state of CVE-2026-27212.

9.2 DOM injection through render hooks

Several options accept HTML strings or render functions that produce HTML: pagination.renderBullet/renderFraction/renderProgressbar/renderCustom, virtual.renderSlide/renderExternal, and the Manipulation methods (appendSlide, prependSlide, addSlide) accept raw HTML strings.

Warning

Treat all of these as innerHTML sinks. Never pass unescaped user content into render hooks or appendSlide/addSlide. Escape or sanitize first, or build HTMLElements yourself rather than passing HTML strings.

9.3 Web component & Shadow DOM

The <swiper-container> element injects styles into a Shadow Root. One closed community issue (#8169) reported a NotAllowedError setting adoptedStyleSheets on a ShadowRoot in certain environments — a robustness rather than confidentiality concern, but worth noting for constrained runtimes (e.g. some embedded/CSP-restricted contexts).

9.4 Hardening checklist

  • [ ] Pin to the latest patched swiper@12 release; watch the tracker for CVE follow-ups.
  • [ ] Sanitize any externally sourced data before it reaches the options object (guard against __proto__/constructor keys).
  • [ ] Sanitize/escape content used in renderBullet/renderSlide/appendSlide/addSlide.
  • [ ] Apply a Content Security Policy; Swiper does not require eval or remote script.
  • [ ] If embedding via the web component, verify adoptedStyleSheets support in your target runtimes.

10. Performance Tuning

Lever Effect
Core + per-module imports Smallest bundle; the bundle build ships every module
Virtual module Keeps only near-viewport slides in the DOM for large data sets
lazyPreloadPrevNext Limit preloaded neighbor slides
cssMode: true Offload movement to native CSS Scroll Snap (with the feature caveats in §4.6)
resizeObserver (default on) Cheaper container-resize detection than window resize
observer/observeParents Use only when contents actually change; mutation observation has a cost
roundLengths Avoids sub-pixel blur; minor cost
maxBackfaceHiddenSlides Tune the Safari flicker workaround; keep low on huge slide counts
watchSlidesProgress Enables per-slide visibility classes — only enable if you use them

Tip

For content- or image-heavy carousels with many slides, the highest-impact change is the Virtual module. For simple sliders that don't need Swiper's richer features, cssMode can substantially reduce JS work.


11. Development & Contributing

  • Edit source only. Per the README, all changes go into src/; dist/ is generated and must not be hand-edited.
  • Source of truth for the API is the TypeScript declarations under src/types/ — option/method/event descriptions and defaults live in their JSDoc.
  • Validate before committing: npm run validate (Prettier check + ESLint). The full npm test runs validate then a production build.
  • Playgrounds: npm run core | react | vue | element build and serve the matching example app under playground/ via Vite; npm run demos serves the broader demos/ site. Use these to manually verify behavior across all four targets.
  • Releases: npm run release runs validation then the release script; npm run changelog regenerates CHANGELOG.md using the Angular conventional-changelog preset.
  • Conventions: ESLint (airbnb-base) + Prettier are enforced; the codebase is ESM-only.

12. Known Issues & Improvement Areas

Drawn from the project's issue tracker (community-reported). These reflect real, open friction points an integrator may encounter and a maintainer may prioritize.

12.1 Loop mode

Loop mode is the most frequent source of open issues:

  • #8076 — loop mode not working correctly in some configurations.
  • #7586 — Swiper warns about a "wrong number of slides for loop mode" even when the count seems valid.
  • #8178 — loopAdditionalSlides doesn't behave as expected in certain conditions.
  • #7478 / #8095 — slideToClickedSlide + centeredSlides + loop interactions break the loop or block link clicks.
  • #7254 — request to set a fixed number of duplicated slides to stabilize loop behavior.

Note

The recurring theme: loop's slide-rearrangement interacts badly with centeredSlides, slideToClickedSlide, and fractional slidesPerView. When auditing a looped slider, test these combinations explicitly and prefer realIndex/slideToLoop in app code.

12.2 Accessibility

  • #8181 — improve accessibility in loop mode.
  • #7975 — redundant aria-disabled added alongside the native disabled attribute on navigation buttons.
  • #5844 — option to disable the span.swiper-notification live region.

12.3 Web component (Element) parity

  • #8125 — <swiper-container> doesn't render the last two slides with loop + slidesPerView="auto" + custom slide width.
  • #7151 — pagination dots malfunction in loop mode in the Svelte/Element integration.
  • #8173 — request to expose isEnd/isBeginning state on the host element for CSS styling.

12.4 Effects & rendering

  • #8168 — Cube (and possibly other) effects show graphics glitches on Electron/WebKit.
  • #8161 — pagination button icons slightly clipped.

12.5 Feature requests of note

  • #8086 / #6882 — desktop zoom and single-click zoom enhancements.
  • #8174 — expose isFullyVisible in the React SwiperSlide render props.
  • #8164 — ship built-in classes at 0 specificity for easier overriding.

12.6 Maintainer-facing observations

  • Loop semantics need clearer guardrails. Several issues stem from users not satisfying loop's slide-count requirements; surfacing the requirement earlier (or auto-correcting more aggressively than loopAddBlankSlides) would reduce churn.
  • Element/web-component parity lags the React/Vue wrappers in a few cases (last-slides rendering, pagination in loop, exposing state to the host). Integrators targeting the web component should test the specific feature combinations above.
  • Security follow-through. With an open "incomplete fix" on a CVE (#8189), integrators should pin to the latest patch and maintainers should prioritize closing the prototype-pollution thread and backports.

13. Quick Reference

Need Do
Install npm install swiper
Core import import Swiper from 'swiper' + import 'swiper/css'
Add a module import { X } from 'swiper/modules' → modules:[X] → import 'swiper/css/x'
Everything at once import Swiper from 'swiper/bundle' + import 'swiper/css/bundle'
React import { Swiper, SwiperSlide } from 'swiper/react'
Vue import { Swiper, SwiperSlide } from 'swiper/vue'
Web component import { register } from 'swiper/element/bundle'; register()
Build (prod) npm run build:prod → dist/
Validate npm run validate
Active index swiper.activeIndex (swiper.realIndex in loop)
Navigate in code slideNext() / slidePrev() / slideTo(i) / slideToLoop(i)
Recalculate swiper.update() or observer:true
Tear down swiper.destroy()