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

@aotr/open-a11y

v2.2.1

Published

Open-source accessibility widget with 30 tools for Vanilla JS, React, Vue, Svelte, Angular, Laravel, Blade, and Livewire. WCAG-focused, MIT, self-hosted.

Readme

open-a11y

One accessible widget, every frontend. A framework-agnostic accessibility toolbar with 30 tools, 7 profiles, persistence, keyboard shortcuts, and adapters for Vanilla JS, React, Vue, Svelte, Angular, Laravel Blade, and Livewire.

npm CI License: MIT

Live demos · Documentation · Examples · Laravel package · Changelog

open-a11y Vanilla demo


Why open-a11y

  • One engine, no duplicate runtimes. Every adapter consumes the same engine, locale table, CSS injector, and widget session registry.
  • Real accessibility controls. Contrast, text scaling, spacing, readable fonts, focus visibility, motion control, reading aids, and keyboard navigation.
  • Canonical state. Profiles and individual tools write the same vocabulary; legacy saved settings are migrated on hydration.
  • Bring your own design. Position, panel side, offset, blur, button size, brand colors, labels, footer, and language are configuration.
  • Small by default. The core and adapters are minified; adapters import the core instead of bundling it again.
  • MIT licensed. Use it in commercial and open-source projects.

What users can do

| Category | Tools and capabilities | | ------------------ | -------------------------------------------------------------------------------------------------------------------- | | Reading | Font Size, Font Weight, Line Height, Letter Spacing, Dyslexia Font, Readable Font, Underline Links | | Content visibility | Highlight Links, Highlight Titles, Hide Images | | Color and contrast | Monochrome, Low Saturation, High Saturation, High Contrast, Light Contrast, Dark Contrast, Invert | | Text alignment | Align Left, Align Center, Align Right, Justify | | Navigation | Big Cursor, Visible Focus, Alt+A / Alt+R shortcuts, skip links | | Reading and focus | Reading Guide, Reading Ruler, Reading Mask, Focus Mode, Screen Reader | | Motion | Stop Animations, Reduced Motion | | Profiles | Seizure Safe, Vision Impaired, ADHD Friendly, Cognitive Disability, Keyboard Navigation, Blind Users, Motor Impaired | | Preferences | Language, reset, persistent settings, optional hide-button toggle | | Integration | Vanilla, React, Vue, Svelte, Angular, Blade, Livewire, and Inertia demos |

How open-a11y compares

This is a capability comparison, not a legal-compliance certification. “Typical SaaS overlay” represents products such as UserWay, accessiBe, EqualWeb, and AudioEye; plans and features vary by vendor and contract.

| Capability | open-a11y | Typical SaaS overlay | | --------------------------------------- | --------- | -------------------- | | Open source and MIT licensed | Yes | No | | Self-hosted, no vendor script required | Yes | No | | Framework-native adapters | Yes | Partial / script tag | | Client-side accessibility toolbar | Yes | Yes | | Accessibility profiles | Yes | Yes | | Reading, focus, and motion aids | Yes | Yes | | Brand, size, and position customization | Yes | Plan-dependent | | Keyboard shortcuts | Yes | Yes | | Preference persistence | Yes | Yes | | CSP nonce support | Yes | Varies | | Laravel / Blade / Livewire support | Yes | No | | Automated page audit | Planned | Yes | | AI auto-remediation | No | Yes | | Managed monitoring and reports | No | Yes | | Legal / compliance support | No | Yes | | Recurring per-site subscription | None | Yes |

Roadmap

| Planned capability | Status | What it adds | | -------------------------- | ------ | ------------------------------------------------------ | | Automated audit mode | Next | Scan the page with axe-core and report violations | | Read aloud | Next | Read selected text or the page with the Web Speech API | | Page structure navigator | Next | List headings and landmarks, then jump to sections | | Word and paragraph spacing | Next | Complete the WCAG 1.4.12 text-spacing controls | | Plugin API | Later | Register custom tools and profiles without forking | | RTL and Arabic/Hebrew | Later | Right-to-left layout and additional locales | | Cookie and server storage | Later | Persist preferences for SSR and logged-in users | | Form helper | Later | Highlight labels, required fields, and errors |

Common questions

Is open-a11y an overlay? It is a client-side preference toolbar. It changes CSS and adds optional reading and focus aids. It does not claim to remediate inaccessible markup or make a site legally compliant.

Does it make my site WCAG compliant? No. It is one part of an accessibility program. You still need semantic HTML, keyboard testing, screen-reader testing, manual audits, and fixes in your own components.

Does it work with Laravel? Yes. The separate aotr/open-a11y-laravel package ships Blade, Livewire, and Inertia React/Vue/Svelte support plus a standalone browser bundle. No Node build is required for the Blade and Livewire components.

Is it free? Yes. The core and Laravel packages are MIT licensed. There is no per-site subscription and no vendor script to load.

Does it support React, Vue, Svelte, and Angular? Yes. Each framework has a thin adapter over the same engine and web components.

Where are preferences stored? The default adapter uses localStorage. The core also accepts a custom storage adapter; server-side sync is not included.

Adapters

| Runtime | Entry | Peer dependency | | ------------------------ | --------------------------------------------------------------------- | -------------------- | | Vanilla / Web Components | @aotr/open-a11y | none | | React | @aotr/open-a11y/react | react >=17 | | Vue | @aotr/open-a11y/vue | vue >=3.5 | | Svelte | @aotr/open-a11y/svelte | svelte >=5 | | Angular | @aotr/open-a11y/angular | @angular/core >=17 | | Laravel Blade + Livewire | aotr/open-a11y-laravel | PHP 8.2+ |

Install

npm install @aotr/open-a11y

React applications also need React installed. Vue, Svelte, and Angular adapters are optional peer entries; install the framework you use.

Quick start

Vanilla JavaScript

import {
  AccessibilityEngine,
  localStorageAdapter,
  createAccessibilityUI,
  mergeConfig,
} from "@aotr/open-a11y";

const engine = new AccessibilityEngine({
  storage: localStorageAdapter,
  config: mergeConfig({
    position: "bottom-right",
    brand: { primary: "#1f4bd8", accent: "#b23a25" },
  }),
});

await engine.init();
createAccessibilityUI(engine);

The widget is a pair of web components (<asw-widget> and <asw-menu>), so it works in any framework or plain HTML.

React

"use client";

import { AccessibilityEngine, localStorageAdapter } from "@aotr/open-a11y";
import { AccessibilityProvider, AccessibilityWidget } from "@aotr/open-a11y/react";

const engine = new AccessibilityEngine({ storage: localStorageAdapter });

export function Root({ children }) {
  return (
    <AccessibilityProvider engine={engine} autoInit>
      <AccessibilityWidget />
      {children}
    </AccessibilityProvider>
  );
}

Vue

import { createApp } from "vue";
import { AccessibilityEngine, localStorageAdapter } from "@aotr/open-a11y";
import { createAccessibilityPlugin } from "@aotr/open-a11y/vue";

const engine = new AccessibilityEngine({ storage: localStorageAdapter });
const app = createApp(App);

app.use(createAccessibilityPlugin(engine, { showWidgetOnMount: true }));
app.mount("#app");

Use useAccessibility() inside any component for reactive settings and actions. <A11yWidget /> is available for declarative mounting.

Svelte

<script lang="ts">
  import { AccessibilityEngine, localStorageAdapter } from '@aotr/open-a11y'
  import { createAccessibilityStore, accessibilityWidget } from '@aotr/open-a11y/svelte'

  const engine = new AccessibilityEngine({ storage: localStorageAdapter })
  const a11y = createAccessibilityStore(engine)
</script>

<div use:accessibilityWidget={{ engine }}></div>

Angular

import { bootstrapApplication } from "@angular/platform-browser";
import { provideAccessibility } from "@aotr/open-a11y/angular";
import { AccessibilityEngine, localStorageAdapter } from "@aotr/open-a11y";
import { App } from "./app";

const engine = new AccessibilityEngine({ storage: localStorageAdapter });

await engine.init();
bootstrapApplication(App, {
  providers: [provideAccessibility(engine)],
});
import { Component, afterNextRender, inject } from "@angular/core";
import { AccessibilityService, mountAccessibilityWidget } from "@aotr/open-a11y/angular";

@Component({ selector: "app-root", template: "" })
export class App {
  readonly service = inject(AccessibilityService);

  constructor() {
    afterNextRender(() => mountAccessibilityWidget(this.service, { side: "right" }));
  }
}

Laravel

composer require aotr/open-a11y-laravel
<x-open-a11y::widget :config="['position' => 'bottom-right']" />
<livewire:open-a11y::widget />

The companion package ships the standalone browser bundle, asset publishing, and reactive Livewire controls. See the Laravel README.

Configuration

import { mergeConfig } from "@aotr/open-a11y";

const config = mergeConfig({
  side: "right",
  position: "bottom-right",
  offset: [20, 20],
  blur: true,
  buttonSize: 56,
  buttonSizeMobile: 44,
  showButton: true,
  defaultLanguage: "en",
  labels: {
    "widget.menuTitle": "Accessibility options",
  },
  brand: {
    name: "Acme",
    url: "https://example.com",
    footerText: "Accessibility tools by Acme",
    primary: "#1f4bd8",
    primaryDark: "#1739a8",
    accent: "#b23a25",
  },
  features: {
    tools: { "dark-contrast": false },
    profiles: { "seizure-safe": true },
    languageChange: true,
  },
});

Explicit createAccessibilityUI(engine, options) values override the engine config for that mount. createAccessibilityUI accepts position, side, offsetX, offsetY, blur, container, and config.

Canonical state

Exclusive tools store the active ID under their group key:

{
  contrast: 'high-contrast',       // or false
  textAlign: 'text-align-center',  // or false
  fontSize: 1.5,
  lineHeight: 1.4,
  letterSpacing: 2,
  'font-weight': true,
  activeProfile: 'vision-impaired',
}

Legacy keys such as 'high-contrast': true are migrated during hydration.

CSP nonce

import { setStyleNonce } from "@aotr/open-a11y";

setStyleNonce(document.querySelector<HTMLMetaElement>('meta[name="csp-nonce"]')?.content);

Every injected accessibility stylesheet carries the nonce.

Live demos

Try the hosted demos at aotr.github.io/open-a11y.

Each demo is a standalone app with the same customization panel and state inspector:

| Adapter | Command | URL | | ---------------- | ------------------------------------------------------------- | --------------------- | | Vanilla | npm run demo:vanilla | http://localhost:4174 | | React | npm run demo:react | http://localhost:4175 | | Vue | npm run demo:vue | http://localhost:4176 | | Svelte | npm run demo:svelte | http://localhost:4177 | | Angular | npm run demo:angular | http://localhost:4178 | | Blade + Livewire | see Laravel repo | http://localhost:4179 |

Run npm run build:demos to assemble all apps into site/, or npm run build once before starting a demo. Each app has its own source and package.json; see examples/README.md.

Package exports

| Path | Contains | | ---------------------------- | -------------------------------------------------------------- | | @aotr/open-a11y | engine, storage, config, tools, profiles, i18n, web components | | @aotr/open-a11y/react | provider, hooks, widget, inline panel | | @aotr/open-a11y/vue | plugin, composable, widget component | | @aotr/open-a11y/svelte | readable store, widget action | | @aotr/open-a11y/angular | providers, signal service, mount helper | | @aotr/open-a11y/styles.css | optional base stylesheet | | @aotr/open-a11y/browser | standalone IIFE bundle for script tags |

Development

npm install
npm run lint        # vp check: format, lint, type-check
npm test            # vp test (Vitest 5)
npm run build       # Rollup runtime bundles + tsc declarations + ng-packagr
npm run build:demos # vp build for every app, assembled into site/
npm run test:dist

Development, checks, tests, and demo builds run through Vite+ (vp check, vp test, vp dev, vp build). The library bundle stays on Rollup because it must emit shared-entry ESM/CJS adapters plus a standalone IIFE; Angular declarations are built with ng-packagr so AOT consumers receive provider metadata.

Deep dives live in docs/:

Browser support

Modern browsers with Custom Elements, Shadow DOM, CSS custom properties, and ES2020. That includes Chrome, Edge, Firefox, and Safari from the last two major versions.

Contributing

Read CONTRIBUTING.md. Bug reports and adapter examples are welcome.

License

MIT © Animesh Chakraborty