← Back to archive

Repo of the Day

jelly-org/ui: Soft, tactile components for product interfaces. Native forms, keyboard access, standard events and just one module import.

Published: Aug 30, 2026

Open repository ↗

Soft, tactile components for product interfaces. Native forms, keyboard access, standard events and just one module import. - jelly-org/ui

Summary

Jelly UI is a zero-runtime-dependency Web Components library written in strict TypeScript and bundled with Vite into a single ESM file. It pairs native form controls (focus, keyboard behavior, standard events, FormData participation) with canvas-painted surfaces that animate with soft-body physics, so each press and toggle wobbles back to rest.

What it is useful for

Jelly UI fits when you want a component library that drops into any framework (or none) without a build step, while still behaving like the platform. Every entry — jelly-button, jelly-input, jelly-switch, jelly-select, jelly-checkbox, jelly-slider, jelly-dialog, jelly-toaster, and others — is a custom element with shadow-DOM encapsulation.

Form controls participate in FormData via ElementInternals, so <jelly-input name="email"> is included automatically in new FormData(form). Buttons with type="submit" and type="reset" drive the closest light-DOM <form>. Events stay unprefixed: chips emit remove, collapsibles emit toggle, menus emit select, and OTP emits change (plus a complete alias carrying the value) when a code is entered.

Accessibility is built in. The README documents WCAG AA contrast in light and dark, ARIA patterns for combobox/listbox select, tablist tabs, roving-focus menus, modal dialogs with scroll lock and focus restore, Shift+Arrow fast-stepping on sliders, forced-colors fallbacks, and prefers-reduced-motion swapping wobble for instant feedback. Theming flows through CSS custom properties (--jelly-color-*, --jelly-accent, --jelly-fill), with three application paths: a <jelly-theme> provider, setThemeMode() from JS, or plain CSS overrides. Variants white, rose, amber, azure, mint, platinum, and graphite adapt automatically to dark mode.

Limitations worth flagging: Jelly UI targets current Chrome, Edge, Safari, and Firefox only, because it leans on Custom Elements, Shadow DOM, ElementInternals, ResizeObserver, Canvas 2D, color-mix(), and CSS logical properties. OTP inputs stay left-to-right by design even in RTL contexts.

How engineers can use it

The documented production entry point is one import:

<script type="module" src="https://jelly-ui.com/package.js"></script>

<jelly-theme mode="auto">
  <jelly-button variant="mint">Publish</jelly-button>
  <jelly-input name="email" type="email" placeholder="[email protected]"></jelly-input>
  <jelly-switch checked>Notifications</jelly-switch>
</jelly-theme>

For local development, the README lists:

npm install
npm run build      # emit dist/jelly.js + dist/jelly.d.ts
npm run serve      # static server -> http://localhost:4173

For an inner loop, run npm run dev (vite build --watch) and npm run serve in a second terminal; reload after each save. Other documented scripts: npm run typecheck (strict tsc --noEmit), npm test (Vitest + Playwright Chromium in real browsers), npm run docs (regenerates docs/content/data.js from the manifest), and npm run build:site (assembles _site/ for GitHub Pages).

To override tokens, drop plain CSS in scope:

:root {
  --jelly-color-background-accent: #7C3AED;
}

The library is MIT-licensed; bundled Fluent System Icons are also MIT.