Skip to content

Installation

sorta11y is a pre-release. Install it via the alpha tag, or pin the exact version if you want to be sure nothing moves under you.

Terminal window
npm install sorta11y@alpha
import Sorta11y from "sorta11y";
import "sorta11y/style.css";

The package exposes three entry points:

SpecifierWhat it is
sorta11yThe library (src/sorta11y.js)
sorta11y/style.cssStructural and state CSS hooks
sorta11y/locales/*Optional locale files (de, en) — see i18n

TypeScript declarations ship with the package — there is no @types/sorta11y to install. They cover require("sorta11y"), import Sorta11y from "sorta11y" and, on a page that loads the <script>, the global Sorta11y, as well as the locale files and the stylesheet import. The option, event and label types live on the Sorta11y namespace:

import Sorta11y from "sorta11y";
const options: Sorta11y.Options = {
handle: ".drag-handle",
onChange: (evt: Sorta11y.SortEvent) => save(evt.order),
};
const list: Sorta11y = Sorta11y.create("#tasks", options);

Named imports work as well — import { create } from "sorta11y" — in bundlers and in Node’s native ESM loader alike.

The file is a UMD bundle, so a plain <script> tag works and puts Sorta11y on window. For a quick trial, the moving alpha tag is fine:

<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/sorta11y@alpha/src/sorta11y.css"
/>
<script src="https://cdn.jsdelivr.net/npm/sorta11y@alpha/src/sorta11y.js"></script>

unpkg.com works the same way.

For production, pin the exact version so a new pre-release can’t change behaviour under you, and add Subresource Integrity (integrity + crossorigin="anonymous") so the browser refuses a file that doesn’t match the one you reviewed:

<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/sorta11y@0.1.0-alpha.1/src/sorta11y.css"
integrity="sha384-HASH_FROM_JSDELIVR"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/sorta11y@0.1.0-alpha.1/src/sorta11y.js"
integrity="sha384-HASH_FROM_JSDELIVR"
crossorigin="anonymous"
></script>

Replace each placeholder with that file’s hash: the package page on jsDelivr shows the SRI hash for every file of every version. A hash matches exactly one file, so:

  • the moving @alpha tag can’t carry one — SRI needs the pinned version;
  • every file you load, locale files included, needs its own integrity;
  • when you bump the pinned version, update the hashes with it.

There is no build step between the source and what you ship — src/sorta11y.js is the file. If you would rather vendor it, copy src/sorta11y.js and src/sorta11y.css out of the repository and serve them yourself.

sorta11y.css is tiny and deliberately unopinionated: a screen-reader-only helper class for the live region, position: relative on items so a grabbed row can lift above its neighbours, two state hooks, and a prefers-reduced-motion rule. It contains no visual styling — that part is yours, see Styling.

You do need to load it. Without the .s11y-visually-hidden rule the live region and the keyboard instructions become visible on the page.

  • Browsers: evergreen Chromium (Chrome/Edge), Firefox and Safari. The drag layer builds on Pointer Events with setPointerCapture, so there is no Internet Explorer support. Details in Browser & AT support.
  • Node: only for development — Node 22.22+ or 24.15+ to run the test suite and to build this documentation site. The library itself runs entirely in the browser and has no runtime dependencies.
<ul id="check">
<li data-id="a">First</li>
<li data-id="b">Second</li>
</ul>
<script>
const list = Sorta11y.create(document.querySelector("#check"));
console.log(list.toArray()); // ["a", "b"]
</script>

Tab to the first item, press Space, then ↓, then Space again. The order should change and, with a screen reader running, each step should be spoken. Next: Quick start.