Pelagic UI The accessible component library for every framework
One design system shipped as native packages for React, Vue, Angular, Svelte, Astro, React Native and Flutter. Same names, same props, same look — and accessibility tested on every build.
npm i pelagic - WCAG 2.2 AA
- 5,540 contrast checks
- 21 themes
- MIT licensed
The same card on every platform
import { useState } from 'react';
import { Card, Input, Segmented, Switch, ProgressBar, Badge, Button, toast } from '@pelagic-ui/react';
const envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
export function Deploy() {
const [env, setEnv] = useState('preview');
const [notify, setNotify] = useState(true);
return (
<Card
title="New deployment"
footer={<Button onClick={() => toast.success('pelagic-app is live')}>Deploy</Button>}
>
<Input label="Project name" defaultValue="pelagic-app" />
<Segmented label="Environment" options={envs} value={env} onChange={setEnv} />
<Switch label="Notify the team" showLabel checked={notify} onChange={setNotify} />
<ProgressBar value={72} label="Build progress" />
<Badge variant="success">Checks passed</Badge>
</Card>
);
} <script setup lang="ts">
import { ref } from 'vue';
import { Card, Input, Segmented, Switch, ProgressBar, Badge, Button } from '@pelagic-ui/vue';
const envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
const name = ref('pelagic-app');
const env = ref('preview');
const notify = ref(true);
</script>
<template>
<Card title="New deployment">
<Input v-model="name" label="Project name" />
<Segmented v-model="env" label="Environment" :options="envs" />
<Switch v-model="notify" label="Notify the team" />
<ProgressBar :value="72" label="Build progress" />
<Badge variant="success">Checks passed</Badge>
<template #footer>
<Button>Deploy</Button>
</template>
</Card>
</template> import { Component, signal } from '@angular/core';
import { PELAGIC_UI } from '@pelagic-ui/angular';
@Component({
selector: 'app-deploy',
imports: [PELAGIC_UI],
template: `
<pl-card title="New deployment">
<pl-input label="Project name" [(value)]="name" />
<pl-segmented label="Environment" [options]="envs" [(value)]="env" />
<pl-switch label="Notify the team" [(value)]="notify" />
<pl-progress-bar [value]="72" label="Build progress" />
<pl-badge variant="success">Checks passed</pl-badge>
<div plCardFooter><button plButton>Deploy</button></div>
</pl-card>`,
})
export class DeployComponent {
envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
name = signal('pelagic-app');
env = signal('preview');
notify = signal(true);
} <script lang="ts">
import { Card, Input, Segmented, Switch, ProgressBar, Badge, Button } from '@pelagic-ui/svelte';
const envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
let name = $state('pelagic-app');
let env = $state('preview');
let notify = $state(true);
</script>
<Card title="New deployment">
<Input bind:value={name} label="Project name" />
<Segmented bind:value={env} label="Environment" options={envs} />
<Switch bind:checked={notify} label="Notify the team" />
<ProgressBar value={72} label="Build progress" />
<Badge variant="success">Checks passed</Badge>
{#snippet footer()}
<Button>Deploy</Button>
{/snippet}
</Card> ---
import Card from '@pelagic-ui/astro/components/Card';
import Input from '@pelagic-ui/astro/components/Input';
import Segmented from '@pelagic-ui/astro/components/Segmented';
import Switch from '@pelagic-ui/astro/components/Switch';
import ProgressBar from '@pelagic-ui/astro/components/ProgressBar';
import Badge from '@pelagic-ui/astro/components/Badge';
import Button from '@pelagic-ui/astro/components/Button';
const envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
---
<Card title="New deployment">
<Input label="Project name" value="pelagic-app" />
<Segmented name="env" label="Environment" options={envs} />
<Switch label="Notify the team" checked />
<ProgressBar value={72} label="Build progress" />
<Badge variant="success">Checks passed</Badge>
<Button slot="footer">Deploy</Button>
</Card> import { useState } from 'react';
import { Card, Input, Segmented, Switch, ProgressBar, Badge, Button } from '@pelagic-ui/react-native';
const envs = [{ label: 'Preview', value: 'preview' }, { label: 'Production', value: 'prod' }];
export function Deploy() {
const [env, setEnv] = useState('preview');
const [notify, setNotify] = useState(true);
return (
<Card title="New deployment" footer={<Button title="Deploy" onPress={deploy} />}>
<Input label="Project name" defaultValue="pelagic-app" />
<Segmented label="Environment" options={envs} value={env} onChange={setEnv} />
<Switch label="Notify the team" checked={notify} onChange={setNotify} />
<ProgressBar value={72} label="Build progress" />
<Badge variant="success">Checks passed</Badge>
</Card>
);
} import 'package:flutter/widgets.dart';
import 'package:pelagic_ui/pelagic_ui.dart';
Widget deployCard() => PelagicCard(
title: 'New deployment',
footer: PelagicButton(label: 'Deploy', onPressed: deploy),
child: Column(children: [
PelagicInput(label: 'Project name', controller: name),
PelagicSegmented<String>(
label: 'Environment',
options: const [
PelagicOption(value: 'preview', label: 'Preview'),
PelagicOption(value: 'prod', label: 'Production'),
],
value: env,
onChanged: setEnv,
),
PelagicSwitch(label: 'Notify the team', value: notify, onChanged: setNotify),
const PelagicProgressBar(value: 0.72, label: 'Build progress'),
const PelagicBadge(label: 'Checks passed', tone: PelagicTone.success),
]),
); Packages
One install — or only what you need
Every platform has its own package and they all read the same tokens. Install pelagic to get everything, or just your framework.
pelagic
npm Everything
7 platforms in one package
The whole system in one install
One package with every target: components for each framework, charts, 3D, icons, illustrations, the theme engine, motion and sound. Framework packages are optional peers, so you only pull in what you import.
- Every framework entry point
- Core CSS, tokens and theme engine
- Icons and illustrations
- WebGL 3D components
npm i pelagic @pelagic-ui/react
npm React 18 / 19
171 components
The most complete set
- DataTable, Tree, VirtualScroller
- 13 accessible chart types
- Motion engine and Wizard
- swal(), toast(), 15 loaders
npm i @pelagic-ui/react @pelagic-ui/core @pelagic-ui/vue
npm Vue 3
33 components
v-model everywhere
- Forms with v-model
- DataTable with cell slots
- Dialog, Drawer, Tooltip
- AccessibilityPanel
npm i @pelagic-ui/vue @pelagic-ui/core @pelagic-ui/angular
npm Angular 20–22
39 components & directives
Standalone, signals, forms
- plButton directive
- Reactive-forms inputs
- DataTable with cell templates
- PELAGIC_UI import bundle
npm i @pelagic-ui/angular @pelagic-ui/core @pelagic-ui/svelte
npm Svelte 5
33 components
Runes-native components
- bind:value forms
- DataTable and Pagination
- Dialog and Drawer
- Skeleton presets
npm i @pelagic-ui/svelte @pelagic-ui/core @pelagic-ui/astro
npm Astro 5
34 components
Zero JS by default
- ThemeScript (no flash of wrong theme)
- Server-sorted DataTable
- Tabs, Dialog, Toaster
- AccessibilityPanel
npm i @pelagic-ui/astro @pelagic-ui/core @pelagic-ui/react-native
npm React Native / Expo
31 components
Same API, native views
- PelagicProvider with every theme
- Forms and DataTable
- Dialog, Drawer, Toast
- RTL via I18nManager
npm i @pelagic-ui/react-native @pelagic-ui/core pelagic_ui
pub.dev Flutter 3.24+
30+ widgets
Pure Flutter, no dependencies
- PelagicApp with every theme
- Forms, tabs, accordion
- Sortable PelagicDataTable
- Bar and line charts
flutter pub add pelagic_ui @pelagic-ui/three
npm WebGL · React
6 WebGL components
3D that follows the theme
- Globe3D and Chart3D
- ModelViewer (glTF)
- ParticlesField, FloatingShapes
- Lazy-loaded three.js
npm i @pelagic-ui/three three @pelagic-ui/icons
npm Every framework
239 icons
239 original duotone icons
- Outline, duotone, solid
- React, Vue, Svelte, Angular, Astro, RN
- Web component + sprite.svg
- Accessible titles
npm i @pelagic-ui/icons @pelagic-ui/illustrations
npm Every framework
24 illustrations
Empty states that match your theme
- 24 themeable scenes
- Pairs with EmptyState
- Web component and raw SVG
- Zero dependencies
npm i @pelagic-ui/illustrations @pelagic-ui/core
npm Framework-agnostic
21 built-in themes
Tokens, CSS and engines
- style.css (65 kB gzip)
- createTheme() with WCAG checks
- data-a11y-* display modes
- Motion and sound engines
npm i @pelagic-ui/core Pelagic UI in numbers
- React components
- 171
- platforms, one design
- 7
- themes + your brand
- 21
- automated contrast checks
- 5,540
- original icons
- 239
- illustrations
- 24
Why Pelagic
Senior-grade defaults, zero setup
Themes are one attribute
Light, dark and high contrast × seven accents × three shapes. Switch with an HTML attribute or scope a theme to any section.
Learn more: Themes are one attributeAccessibility display modes
Contrast schemes, color-vision filters, text size and spacing, reading guide, motion off and large targets — as data-a11y-* attributes.
- Yellow on black
- Grayscale
- Readable font
- Reading guide
- 44px targets
- Motion off
Your brand color, still accessible
createTheme() keeps your hue and tunes lightness until every pair passes WCAG AA in every mode.
createTheme({ primary: '#ff6a00' }) Charts people can use
13 dependency-free types, keyboard navigable, announced, with a data-table fallback.
Learn more: Charts people can useMotion and sound, politely
A spring and timeline engine plus 18 UI sounds. Everything stops for reduced motion.
Learn more: Motion and sound, politelyRTL and Arabic first
Logical CSS everywhere, so a whole interface mirrors with one dir attribute.
239 icons, 24 illustrations
Duotone icons and empty-state scenes that recolor with the theme.
Learn more: 239 icons, 24 illustrationsPelagic Space
Drag and drop, or describe a page in English or Arabic — then export React, Vue, Angular or HTML.
Open Pelagic SpaceLive preview
A real app built with Pelagic UI
Search, filter, sort, paginate, add a member, toggle loading skeletons. Everything below is @pelagic-ui/react and follows the theme.
| Status | |||
|---|---|---|---|
| LHLina Haddad | Design | 7 | Active |
| OSOmar Saleh | Engineering | 12 | Active |
| SNSara Nasser | Product | 4 | Away |
| YKYousef Karim | Engineering | 9 | Active |
| MFMaya Fares | Design | 3 | Active |
Components
143 documented components in 11 categories
Every category page has live demos, props, keyboard support and copy-ready code.
Ship accessible UI on every platform
Free and open source under the MIT license.
npm i pelagic