Accessible Astro Components builds accessibility into the component, not the checklist
A collection of accessible components for Astro projects with built-in ARIA attributes, keyboard navigation and interactive elements. Easy to implement and customize to your needs.
At a glance
- What is it?
- Accessible Astro Components is a library of Astro components that ship with the ARIA attributes, keyboard handling and focus management already written, and the component list shows the scope: dialogs, drawers, tabs, toasts, data tables and a full set of form controls, all with zero runtime dependencies and light-dark theme support. The companion colour contrast checker and the Astrobook preview setup are the parts that make it usable as a design system rather than a grab bag.
- Who is it for?
- Adopt Accessible Astro Components if you build Astro sites and keep writing the same ARIA attributes and focus traps by hand, since the library ships those patterns as components you can preview before adopting. Skip it if you are not on Astro, since these are.astro components and not framework-agnostic web components, and if you need a component the list does not cover.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Astro, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The premise is that accessibility work is repetitive
Accessible Astro Components is described as a comprehensive library of accessible, easy-to-use UI components for Astro, and the framing is worth reading closely.
Each component is built with accessibility in mind, following WCAG guidelines and ARIA best practices, providing a solid foundation for building inclusive web applications. The components are designed to be customizable, performant and developer-friendly, with full TypeScript support.
The underlying observation is that accessibility work is repetitive rather than hard. Every dialog needs the same focus trap, the same escape handling, the same aria-modal and labelled-by attributes. Every disclosure widget needs the same expanded state and the same key handling. Every combobox needs the same listbox relationship. Writing them once per project means writing them badly once per project, and the library is the accumulation of that writing done properly.
The stated mission is to provide developers with accessible, easy-to-use components that make building inclusive web applications simpler and faster, without compromising on customization or performance.
The component features list makes the accessibility claims concrete rather than general. Keyboard navigation with full keyboard support and focus management. Screen readers with proper ARIA labels and semantic HTML. Accessible by default, built following WCAG guidelines and ARIA best practices.
And there are three claims that are about the rest of the web platform rather than about ARIA. Modern CSS using logical properties and modern selectors, which is what makes a component adapt to writing direction without a second stylesheet. Performance tuned for Core Web Vitals. And responsive, mobile-first and touch-friendly design.
The last two features on the list are worth pulling out because they are unusual for a component library. Dark mode supports light and dark themes with the light-dark() function, which is a relatively recent CSS feature and means the theme switch is handled by the browser rather than by a class on a wrapper element. And reduced motion has its own component, a ReducedMotion toggle that respects system preferences, rather than leaving you to guard every animation yourself.
The library is MIT licensed, TypeScript throughout, with the package at version 5.8.1 and the last push on 2026-10-19.
Thirty components, and the list tells you what the hard parts are
The component list is long enough to be a design system inventory, and reading it shows where the difficulty sits.
The interactive primitives that usually get the accessibility work done are all here. Accordion for expandable and collapsible sections for progressive disclosure. Modal for accessible dialog windows. Drawer for a slide-in dialog panel from any screen edge with focus management. Tabs for content organization with tabbed interfaces. Tooltip, which uses the Popover API with CSS Anchor Positioning rather than a hand-rolled positioned div. And Toast with a global window.toast API, plus a separate ToastProvider component that is a positioned live region which renders and manages the toasts.
That split between Toast and ToastProvider is the detail that shows care. A toast has to be announced by a screen reader, and the only correct way to do that is a live region, so the provider owns the live region and the toast is just the item. Splitting them means the announcement behaviour is a property of the container rather than something each caller has to wire up.
Navigation and orientation components are there too. Breadcrumbs as a navigation aid showing the current page's location, Pagination for paginated content, and SkipLink as a keyboard navigation aid for screen readers.
The SkipLink component is the one that shows this library has a point of view. A skip link is the first thing a keyboard user should hit on a page, and having it as a component rather than a snippet means it is present by default rather than remembered.
There are also two components that are about user preferences rather than content. DarkMode is a theme toggle with system preference support and a global API, and HighContrast is a high contrast mode toggle for enhanced visual clarity. Both of those are accessibility settings that most sites leave out, and having them as first-class components is a reasonable opinion.
The forms group is the largest and it is where the labelling work shows. Form is the wrapper with validation and error handling. Input covers text, email, password and other types with validation. Textarea, Checkbox with proper labelling, Radio with proper grouping, Fieldset for field grouping with legend support. And Switch is a toggle switch built on a native checkbox with role="switch", which is the correct construction rather than a styled div with a click handler.
Then the content components. Avatar with support for images, initials and placeholder icons, AvatarGroup for condensed or grid layouts, Badge, Button, Card, Heading with proper accessibility and hierarchy, Link for internal and external navigation, Media as a responsive image component, Notification for info and alert messages, Video as a YouTube embed component, and DataTable, which is described as composable tables with sorting, search, result announcements and optional client pagination.
The DataTable description is the one with the most detail, and result announcements is the interesting part: a filtered table has to tell a screen reader how many rows are now showing, and that is a live region again. Optional client pagination tells you the sorting and search happen in the browser when you want them to.
Installing and the shape of the package
The install is the ordinary three-way choice:
# npm
npm install accessible-astro-components
# pnpm
pnpm add accessible-astro-components
# yarn
yarn add accessible-astro-componentsAnd the quick start shows the import style, which is the Astro convention:
---
import { Accordion, AccordionItem } from 'accessible-astro-components'
---
<Accordion>
<AccordionItem title="Getting Started">Content for the first item...</AccordionItem>
</Accordion>The component and its items are imported by name from the package root, and the markup nests the item inside the component.
The package metadata tells you more about how it is built. The exports map has a root entry with a types condition pointing at the declaration file and a default condition pointing at index.js, and separate entries for the styles, both the index stylesheet and a wildcard for the individual style files, plus the package.json.
That styles export is worth a note. Components that ship their own CSS as separate files, exposed through a wildcard export, is the pattern that lets a consumer import only the styles for the components they actually use, which is the difference between shipping the whole stylesheet and shipping nothing extra.
The files array shows what goes into the published package and, more usefully, what does not. It includes index.js, src/components, src/styles, src/types, the README and the LICENSE, and then excludes the stories files with a pattern, the StorySlot and StorySlotChildren Astro components, and the astrobook.css file.
Those exclusions are the documentation tooling being kept out of the shipped package. The StorySlot components and astrobook.css exist for the Astrobook preview site, and the library excludes them so they do not ship to users.
The zero dependencies claim is visible here too. The dependencies section is absent entirely, and the peer dependency is Astro itself at a range covering 5, 6 and 7. So the components are pure Astro components with nothing else pulled in, and the requirement is on your Astro version rather than on the library's own tree.
The dev dependencies tell you about the documentation setup: Astrobook at 0.12.2 is the component preview tool for Astro, with prettier and a prettier plugin for Astro at 0.8.0 and a plugin for CSS ordering. That last one is a small detail with a purpose, since a CSS ordering plugin enforces a consistent property order so that cascade-related properties do not depend on how the file was edited.
The Node engine range is also specific: 18.20.8 or 20.3.0 or 22 or later, and there is a cliff.toml at the root, which is the tool for generating changelogs from conventional commits.
The wider ecosystem, and the parts that go beyond components
The library is one of six projects under the Accessible Astro name, and the others fill in the gaps a component library leaves.
There is an Accessible Astro Starter, described as a fully accessible starter for kickstarting Astro projects, with Tailwind. There is an Accessible Astro Dashboard, a user-friendly dashboard interface with a login screen and widgets. There is an Accessible Astro Launcher, a command palette or launcher component. And there is Accessible Astro Docs, comprehensive documentation for all the Accessible Astro projects.
Then the one that is not a component at all. The Color Contrast Checker is a WCAG-compliant colour contrast checker with design system token generation.
That last one is the piece that makes the ecosystem a system rather than a collection. Contrast is the accessibility failure that automated checks catch best and that design tokens solve best, and a tool that checks contrast and emits tokens closes the loop between the components and the palette you feed them.
There is a roadmap on the project board as well, and the contributing section is unusually specific about what it wants. Filing an issue, submitting a pull request, starting a discussion, and supporting on Open Collective. And the support section explains the practical reason, which is that support helps cover basic costs and continue building access.
So the funding model is a sponsorship through Open Collective, which for a library like this is a reasonable fit, since accessibility work is ongoing maintenance of WCAG conformance as the guidelines evolve rather than a one-off build.
The repository layout matches the structure. There is src/ for the components, styles and types, an index.js entry point, astro.config.mjs for the site build, tsconfig.json, a package-lock.json, a .prettierrc with a .prettierignore, an AGENTS.md, a cliff.toml for the changelog and a .github directory.
The main entry point is index.js at the root, and the types entry is the declaration file under src/types, so the package ships compiled or generated types alongside the Astro components rather than requiring the consumer to process them.
What to weigh before adopting it
The honest assessment has a few parts.
The strongest argument for the library is the one the component list makes: the interactive patterns are where accessibility goes wrong most often, and they are the same for everyone. A dialog that traps focus, restores it on close, handles escape and is labelled correctly is a few hundred lines of careful code, and the library has that in a form you can read.
The second argument is the compatibility surface. The components are Astro components with no client-side framework bundled, which means the interactive ones must ship their own script. That is the right trade for a library that claims zero dependencies, and it also means the components follow Astro's island model rather than hydrating a framework tree.
The main limitation is that it is Astro only. There is no React or Vue or Svelte version here, and there is no web-component build, so if your project is not Astro this library does not apply. The peer dependency range spanning Astro 5 to 7 is generous, and the components directory is .astro files, which means there is no framework abstraction to preserve.
The second limitation is the usual one for a component library of this size, and the project is honest about the surface. Thirty components with an ARIA contract each is a lot of behaviour to keep consistent with the ARIA authoring practices as they are revised. The version line at 5.8.1 with releases through 2026 suggests active maintenance, and the last push was on 2026-10-19, but a version 5 line means the API has already moved through five breaking changes.
The third is that a component can only be as accessible as its content. A modal with an accessible structure and a heading that is not a heading is not an accessible dialog, and the library cannot prevent that. What it does is remove the failure modes that come from forgetting the plumbing, which is the larger share of them.
For a team that already uses Astro and has a design system, the practical question is whether these components match the design system or replace it. Given that the components are designed to be customizable, with styling that is exposed through the styles export, that is a project decision rather than a library limitation.
Editorial conclusion
Adopt Accessible Astro Components if you build Astro sites and keep writing the same ARIA attributes and focus traps by hand, since the library ships those patterns as components you can preview before adopting. Skip it if you are not on Astro, since these are.astro components and not framework-agnostic web components, and if you need a component the list does not cover. Verify first which Astro version you are on, since the peer dependency range spans 5 through 7, and that you read the accessibility notes for the components you use, because a component cannot be accessible if the content you put in it is not.
Frequently asked questions
What does Accessible Astro Components include?
The components cover accordion, avatar and avatar group, badge, breadcrumbs, button, card, dark mode toggle, data table, drawer, high contrast toggle, reduced motion toggle, a full forms group, heading, link, media, modal, notification, pagination, skip link, tabs, toast and toast provider, tooltip and video. The forms group includes Form, Input, Textarea, Checkbox, Radio, Switch and Fieldset, and the Tooltip uses the Popover API with CSS Anchor Positioning.
How do I install Accessible Astro Components and use a component?
Install it with npm, pnpm or yarn using the accessible-astro-components package name. In an Astro file you import the components by name from the package root, for example `import { Accordion, AccordionItem } from 'accessible-astro-components'`, and then nest the item inside the component with a title prop. The package has no runtime dependencies and requires Astro 5, 6 or 7 as a peer dependency.
Which accessibility features are built into the components?
They are built following WCAG guidelines and ARIA best practices, with full keyboard support and focus management, proper ARIA labels and semantic HTML, and support for screen readers. Dark mode uses the light-dark() function for light and dark themes, there is a reduced motion toggle that respects system preferences, and the data table includes result announcements while the toast provider renders a positioned live region.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/incluud-accessible-astro-components)Was this useful?