{
  "markdown": "<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"brand/liquefy-logo-dark.svg\">\n  <img alt=\"liquefy-ui\" src=\"brand/liquefy-logo.svg\" width=\"264\">\n</picture>\n\nA TypeScript UI library that delivers highly transparent Liquid Glass through WebGL optics, physical springs, and accessible React primitives.\n\n![A glass lens dragged across a wordmark, bending the letters and the grid behind it at its bezel, and swaying on its springs as it moves](brand/liquefy-lens.gif)\n\n> This is an independent open-source project and is not affiliated with Apple Inc. It references public design principles while providing an original implementation for the web.\n\nNothing above is a video effect: that is a WebGL displacement map applied to the\nlive backdrop through `backdrop-filter`, and the way the shape stretches and\novershoots is a spring reading pointer velocity. Both are on by default. Drag it\nyourself at **[liquefy-ui.com](https://liquefy-ui.com)**, which also hosts the\ncomponent reference and the shadcn registry.\n\n## Packages\n\n| Package | Purpose |\n| --- | --- |\n| `@liquefy-ui/react` | React components, themes, and provider |\n| `@liquefy-ui/core` | Dependency-free WebGL, springs, and motion |\n| `@liquefy-ui/icons` | Tree-shakeable React SVG icons |\n| `@liquefy-ui/mcp` | MCP server that answers component questions from the real API |\n\n## Quick start\n\n```bash\npnpm add @liquefy-ui/react @liquefy-ui/core @liquefy-ui/icons\n```\n\n```tsx\nimport { LiquefyProvider, LiquidButton } from '@liquefy-ui/react'\nimport { SparklesIcon } from '@liquefy-ui/icons'\nimport '@liquefy-ui/react/styles.css'\n\nexport function App() {\n  return (\n    <LiquefyProvider theme=\"system\" tint=\"#8f8f8f\">\n      <LiquidButton iconBefore={<SparklesIcon />}>\n        Create magic\n      </LiquidButton>\n    </LiquefyProvider>\n  )\n}\n```\n\n## Next.js and React Server Components\n\nEvery component needs state, refs or the WebGL lens, so the whole package sits on\nthe client side of an RSC boundary. The published bundles carry a `'use client'`\ndirective, so importing them straight into a server component works — no wrapper\nfile needed. Only event handlers have to move: a function cannot cross from a\nserver component into a client one, so anything with `onClick` or local state\nbelongs in its own `'use client'` component.\n\n`apps/next-example` is a working Next.js 16 App Router app whose page is a server\ncomponent, and its build runs in CI. If the client boundary ever regresses, that\nbuild fails rather than yours.\n\n## Tailwind CSS v4\n\nImport `tailwind.css` instead of `styles.css`, before Tailwind itself:\n\n```css\n@import '@liquefy-ui/react/tailwind.css';\n@import 'tailwindcss';\n```\n\nThat declares the cascade layer order — so `className=\"rounded-full\"` on a\n`LiquidButton` actually wins — and bridges the `--lq-*` tokens into Tailwind's\ntheme as `bg-liquid-accent`, `text-liquid-muted`, `rounded-liquid`,\n`shadow-liquid`, `ease-liquid` and friends. The bridge uses `@theme inline`, which\nis what keeps those utilities resolving per-theme at use time.\n\n## For coding agents\n\n| What | Where |\n| --- | --- |\n| MCP server | `claude mcp add liquefy-ui -- npx -y @liquefy-ui/mcp` — eight tools answering from the real exports, no network, no dependencies |\n| `llms.txt` | [`/llms.txt`](https://liquefy-ui.com/llms.txt) and [`/llms-full.txt`](https://liquefy-ui.com/llms-full.txt), generated from source |\n| One page per component | [`/llms/liquid-button.md`](https://liquefy-ui.com/llms/liquid-button.md), plus `icons.md`, `core.md` and `mcp.md` — plain Markdown, because the docs site is a hash-routed SPA that a fetcher without JavaScript cannot read |\n| shadcn registry | `npx shadcn@latest add @liquefy-ui/liquid-button` — the namespace is in shadcn's registry directory, so it needs no `components.json` entry |\n\nThe MCP tools are `get_conventions`, `list_components`, `get_component`,\n`search_components`, `get_component_source`, `get_tokens`, `list_icons` and\n`get_core_api`. The catalog behind them is generated from source at build time, and\nlists only names the package entry point re-exports — so an agent is never told to\nimport something that does not resolve.\n\nThe registry copies real component source into your project rather than a\nre-export, with imports rewritten to `@/components/ui`, `@/lib` and `@/hooks`. The\ncopied tree keeps `@liquefy-ui/core` and `@base-ui/react` from npm but not\n`@liquefy-ui/react`, so a copied `LiquefyProvider` never ends up competing with the\npackaged one. Every copied file is written with its own `'use client'` directive, so an\nRSC app needs no follow-up edit.\n\n## Documentation\n\nEverything is on **[liquefy-ui.com](https://liquefy-ui.com)**:\n\n| Route | Contents |\n| --- | --- |\n| `#/` | The playground first, then framework and agent-tooling compatibility, then component samples |\n| `#/playground` | Every `LiquefyProvider` prop as a live control, applied to the whole site |\n| `#/components` | Index of every component, each with live demos and a full prop table |\n| `#/docs` | Introduction, installation, provider, theming, the `styles` prop, motion |\n| `#/docs/frameworks` · `#/docs/tailwind` · `#/docs/ai-tooling` | Integration |\n| `#/docs/accessibility` · `#/docs/performance` · `#/docs/troubleshooting` | Practices |\n\nOld `#/guides/*` links redirect to their `#/docs/*` equivalents.\n\n## Style overrides: the `styles` prop\n\nEvery component takes a `styles` prop for one-off overrides, so reaching for a\nstylesheet is optional. It is a superset of `style`:\n\n```tsx\n<LiquidButton\n  styles={{\n    color: 'accent',            // colour words resolve to var(--lq-accent)\n    p: 3,                       // spacing keys count --lq-space units\n    w: { base: '100%', md: 240 }, // responsive, per breakpoint\n    boxShadow: '$shadow',       // $token → var(--lq-token), anywhere in a string\n    _hover: { bg: '$glass-soft' },\n    _dark: { opacity: 0.92 },\n    '&:has(svg)': { gap: 2 },   // raw selectors start with &, at-rules with @\n  }}\n>\n  Create magic\n</LiquidButton>\n```\n\n| Feature | Notes |\n| --- | --- |\n| CSS properties | Every camelCase property, plus `--custom-properties`. Numbers become `px`, matching `style`. |\n| Spacing shorthands | `p`, `px`, `py`, `pt`/`pr`/`pb`/`pl`, and the `m` equivalents. Numbers count `--lq-space` units (`4px` by default, set `spacing` on the provider). `gap` and friends use the same scale. |\n| Other shorthands | `w`, `h`, `size`, `minW`/`maxW`/`minH`/`maxH`, `bg`, `radius`. `radius` drives `--lq-radius`, so the press-squish keeps animating the corners. |\n| Tokens | `$name` anywhere in a string resolves to `var(--lq-name)`. Colour properties also accept the bare words `accent`, `tint`, `foreground`, `muted`, `placeholder`, `text`, `line`. |\n| Responsive | `{ base, sm, md, lg, xl }`, ordered ascending no matter how you write it. Override the widths with `breakpoints` on `LiquefyProvider`. |\n| States | `_hover`, `_focus`, `_focusVisible`, `_active`, `_disabled`, `_checked`, `_selected`, `_expanded`, `_open`, `_invalid`, `_readOnly`, `_placeholder`, `_first`, `_last`, `_odd`, `_even`, and `_dark` / `_light` (which cover both the explicit theme and `theme=\"system\"`). |\n\nStatic values ride the `style` attribute, so the common case adds no stylesheet\nand no hydration concerns. As soon as a state or breakpoint appears, the whole\nobject moves into a generated class instead — otherwise the inline declarations\nwould outrank the very rules meant to override them. That class is inserted\n**unlayered**, and the component stylesheet lives in `@layer liquefy-ui`, so\noverrides win on cascade order rather than on `!important` or specificity.\n\nPrecedence is `styles` over the component's own custom properties, and `style`\nover everything — `style` stays the last-resort escape hatch.\n\n`transform` and `backdrop-filter` are written inline by the jelly springs every\nframe and cannot be overridden through `styles`; development builds warn if you\ntry. Wrap the component and style the wrapper instead.\n\nBuilding your own component on the same system:\n\n```tsx\nimport { useLiquidStyles, type LiquidStyleProps } from '@liquefy-ui/react'\n\nexport const Panel = ({ className, style, styles, ...props }: LiquidStyleProps & JSX.IntrinsicElements['div']) => {\n  const root = useLiquidStyles('my-panel', { className, style, styles })\n  return <div className={root.className} style={root.style} {...props} />\n}\n```\n\nServer rendering: `useInsertionEffect` does not run on the server, so flush the\ncollected rules into the document head yourself with `getLiquefyStyleSheet()`.\nStatic-only `styles` need nothing — they are already inline.\n\n`LiquefyProvider` takes `className` and `style` but not `styles` — it owns the\nconfig that `styles` reads. `LiquidToastProvider` takes none of the three: it\nrenders no root element of its own, only the toast viewport. `slotStyles` is reserved for per-part styling\n(`{ header, body, footer }`) and is not implemented yet.\n\nThe full version of this — every shorthand, token reference, breakpoint and state\nkey, plus custom components and server rendering — is at `#/docs/styles-prop`,\nwith the token system itself at `#/docs/theming`.\n\n## Components\n\n33 components and 44 icons, each with live demos and a full prop table at\n[liquefy-ui.com/#/components](https://liquefy-ui.com/#/components).\n\n| Category | Components |\n| --- | --- |\n| Inputs | `LiquidButton`, `LiquidIconButton`, `LiquidCheckbox`, `LiquidRadioGroup` / `LiquidRadio`, `LiquidSwitch`, `LiquidSlider`, `LiquidTextField`, `LiquidTextArea`, `LiquidSelect`, `LiquidSegmented`, `LiquidRating` |\n| Data display | `LiquidAvatar` / `LiquidAvatarGroup`, `LiquidBadge`, `LiquidChip`, `LiquidTooltip`, `LiquidTable` family, `LiquidList` family, `LiquidDivider` |\n| Feedback | `LiquidAlert`, `LiquidProgress`, `LiquidSpinner`, `LiquidSkeleton`, `LiquidToastProvider` / `useLiquidToast`, `LiquidDialog` |\n| Surfaces | `LiquidSurface`, `GlassCard`, `LiquidAccordion` / `LiquidAccordionItem` |\n| Navigation | `LiquidTabs` family, `LiquidBreadcrumbs`, `LiquidPagination`, `LiquidMenu`, `LiquidDrawer`, `GlassDock` / `DockItem` |\n| Foundation | `LiquefyProvider`, `useLiquefyConfig`, `useLiquidGlass`, `useLiquidStyles`, `getLiquefyStyleSheet`, `defaultBreakpoints` |\n\nWhen WebGL is unavailable, components automatically fall back to the transparent CSS material. Effects default to on everywhere; use the `motion` and `transparency` provider props to tone them down.\n\nUse `theme=\"dark\"`, `theme=\"light\"`, or `theme=\"system\"` on `LiquefyProvider` to control appearance.\n\n## Design notes\n\n- **Real edge refraction**: a WebGL shader bakes a rounded-rect lens displacement map, applied to the live backdrop through an SVG `feDisplacementMap` inside `backdrop-filter` (with per-channel chromatic dispersion). Chromium renders it fully; WebKit and Gecko gracefully fall back to the blurred CSS material.\n- **One shared WebGL context**: browsers cap live WebGL contexts (~16 per page), so every component draws through a single hidden GL canvas and blits into its own 2D canvas. Any number of glass components can coexist.\n- **Jelly physics**: scale, skew, and tilt run on deliberately underdamped springs. Pointer velocity is injected into the springs, so fast sweeps make surfaces sway, and press/release produces several visible overshoots. The shader receives the same energy as `u_wobble` and wiggles the rim in sync.\n- The overlay shader renders SDF-shaped rim light with RGB dispersion, iridescence, pointer glow, press ripples, and a moving sheen — only during interaction and decay, never continuously.\n- Glass is intended for interaction and navigation layers rather than primary content.\n- **Accessibility comes from Base UI**: Dialog, Drawer, Menu, Select, Tooltip, Tabs and Accordion are built on `@base-ui/react`, which supplies focus trapping and restoration, scroll locking, Escape handling, roving tabindex, typeahead, and collision-aware positioning. liquefy-ui keeps the optics and the springs and stops re-implementing the parts that are easy to get subtly wrong. The keyboard behaviour is asserted in `packages/react/test/keyboard.test.tsx` rather than assumed.\n- React and React DOM are peer dependencies, preventing duplicate React bundles.\n- Motion and transparency are **always on by default**, independent of OS accessibility settings (macOS \"Reduce Motion\" / \"Reduce Transparency\" silently flip both media queries in every desktop browser). Toggle them per subtree with `motion={false}` / `transparency={false}` on `LiquefyProvider`; apps that want to honor the OS can pass e.g. `motion={!matchMedia('(prefers-reduced-motion: reduce)').matches}` or use the core-level `respectReducedMotion` / `respectReducedTransparency` options.\n\n## Contributing\n\nIssues and pull requests are welcome. `rc` is the development branch — branch from\nit and open the pull request back into it. [CONTRIBUTING.md](./CONTRIBUTING.md) has\nthe local setup, the test suites, the CI jobs and the commit convention.\n\n## Sponsor\n\n[GitHub Sponsors](https://github.com/sponsors/yu5ag) funds the maintenance of this\nlibrary — the shader work, the browser matrix, and the release plumbing that keeps\n`pnpm add @liquefy-ui/react` boring. Sponsorship goes to the maintainer rather than\nto an organisation; there is one of us.\n\nGitHub takes no cut, so the whole amount arrives. One-off is as welcome as monthly.\n\n## License\n\nMIT\n",
  "bytes": 13364,
  "sha": "abcb0251565e142ff0fdbbacc25180e84a7292254db42932aa6f86cbb28ed6a2",
  "repo_slug": "liquefy-ui/liquefy-ui",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_liquefy_ui_liquefy_ui_df3edb5f/readme"
}