Cross-platform. Agent-aware. Yours to remix.

One component library.
Web, native, electron.
Per-package install, agent-aware.

plyxui is a typed, branded, cross-platform component library. Same source tree for React and React Native via .ts and .native.ts splits. Install only the packages you need: primitives, styles, icons, layouts, navigator. First-party MCP server so coding agents pick components by name.

Get the alphaRead the docs
$npm install @plyxui/core @plyxui/styles @plyxui/primitives
app.tsx
import { ThemeProvider } from "@plyxui/styles";
import { Box, Text, Button } from "@plyxui/primitives";
import { Icon } from "@plyxui/icons";

export default function App() {
  return (
    <ThemeProvider>
      <Box surface="primary" padding="lg">
        <Text size="2xl" weight="bold">Hello.</Text>
        <Button iconLeading={<Icon name="plus" />}>
          New session
        </Button>
      </Box>
    </ThemeProvider>
  );
}

Why this exists

Modern apps want three things from a UI library. Most pick one.

After shipping a few production apps on top of shadcn + Radix + bespoke Electron chrome, the same gaps showed up every time.

Cross-platform is hard.

The same components get rewritten for web, Electron, and React Native. Three branches drift. plyxui ships one tree with .ts and .native.ts splits, so the platform-specific code is bounded and the public API is identical.

Tokens become strings.

Big design systems lose autocomplete on token names, variants, and icons. plyxui tokens are interfaces, augmentable from userland. Names extend; types follow.

Coding agents misimplement.

Cursor and Claude Code scrape docs and guess. plyxui ships a first-party MCP server so agents list, search, install, and lint components conversationally. The agent and the dev pull from the same source.

The idea

Three packages get you a working app. Two more get you a polished one.

Each package does one thing. Install only the layers you need. The MCP server is independent so the agent-friendly bits ship to anyone, not just plyxui users.

01

Foundation

@plyxui/core, @plyxui/styles, @plyxui/primitives. Tokens, theming, Box, Text, Stack, Flex, Input, Button. Cross-platform.

02

Polish

@plyxui/icons, @plyxui/comps, @plyxui/layouts. The icon registry, Modal, Dropdown, AppShell, Sidebar, ScreenContainer.

03

Agent layer

@plyxui/mcp gives coding agents a structured handle on the library. List, describe, install, lint. No HTML scraping.

What's in the box

Nine choices the next library you reach for probably didn't make.

Each of these is shipping in the alpha. Not the roadmap.

Branded tokens

Tokens are interfaces, not enums. Augment from userland; the rest of the library autocompletes against your brand.

Polymorphic Box

as=button, as=a, as=anything. Native attributes type-check. Works exactly as you expect.

.ts / .native.ts splits

Metro picks native, Webpack/Vite/Next/Electron pick web. Same public API, sane platform-specific internals.

Icon registry

Names autocomplete, names extend. Built around a typed registry, not per-file imports.

Router-agnostic

defineRoutes() once, render with the react-router or react-navigation adapter. Same routes table powers Sidebar + tabs.

Layouts that compose

AppShell, Sidebar, ScreenContainer. No router opinion. Drop in anywhere.

Modal and Dropdown

Web uses the native <dialog>. Dropdown is keyboard-aware. Native ports trail by a small margin and are catching up fast.

First-party MCP

@plyxui/mcp gives coding agents a structured handle on the library. List, search, install, lint without scraping HTML.

OS theme follow

ThemeProvider follows prefers-color-scheme until the user explicitly picks. Then it stops listening, by design.

Under the hood

A turborepo with intentional seams.

Each package is its own npm artifact. Each is small enough to read in an afternoon. Each ships on its own changeset cadence.

plyxui/
├── apps/
│   ├── playground-web/      sandbox with the live primitives
│   ├── docs/                next.js + MDX docs site
│   └── landing/             this site
├── packages/
│   ├── core/                tokens, polymorphic types, hooks
│   ├── theme/               ThemeProvider, useTheme (web + native)
│   ├── primitives/          Box, Text, Stack, Flex, Input, Button
│   ├── icons/               Icon component + augmentable registry
│   ├── layouts/             AppShell, Sidebar, ScreenContainer
│   ├── navigator/           router-agnostic adapter
│   ├── comps/               Modal, Dropdown
│   └── mcp/                 first-party MCP server
├── turbo.json
└── tsconfig.base.json

One source tree

Web components live in index.tsx. Native variants live in index.native.tsx. Metro resolves automatically. No runtime branching, no platform flag, no compiler magic.

Augmentable types

Every interface that ships -- token names, icon names, route shapes -- is augmentable from userland. declare module + a runtime register call, and your brand becomes part of the type surface.

cva for variants

class-variance-authority handles className composition. Small, no compiler, drops out of the way the moment a consumer wants their own CSS.

No styled-components

Runtime CSS-in-JS is a hot loop in big design systems. plyxui uses the style prop + cva. Faster on cold start; cheaper to debug.

Agent layer

A first-party MCP server.

Coding agents talk to plyxui through a structured protocol instead of scraping HTML docs. The library and the agent pull from the same source.

@plyxui/mcp

The tools

  • list_components -- enumerate primitives, comps, layouts.
  • describe_component -- props, variants, examples.
  • install_component -- adds the right import + verifies the manifest.
  • lint_usage -- catches drift from the design system in agent edits.
See also

AI Polish

A sibling project: a standalone desktop app that pairs nicely with plyxui. Pick a project folder, paste your Anthropic key, hand the agent a Figma frame. Every Write or Edit is held for Apply / Reject review before it touches a file.

The remix layer

Themes are remixable. Sharing is one link.

Tokens are the primary unit. Component variant overrides are the secondary unit. Bundle both and you have a remix: a complete look that drops into another app's ThemeProvider with one line.

What a remix is

{
  "name": "Warm October",
  "tokens": {
    "primaryOrange": { "light": "#FF7A30", "dark": "#FFA260" },
    "primaryFill":   { "light": "#FFF7EE", "dark": "#1A0F08" }
  },
  "overrides": {
    "Button": { "primary": { "borderRadius": "pill" } }
  }
}

How sharing works

Publish a remix and you get a stable link. Anyone running plyxui can apply it with a single prop:

<ThemeProvider remixUrl="https://plyxui.dev/r/warm-oct" />

Creators can lock a remix (always pull the latest) or open it (consumers can fork and tweak locally). The sharing surface is built on uiverse-style discovery; the consumer experience is one line.

The remix backend is the next milestone. Today, remixes work as local json bundles; the public sharing surface lands with 1.0.

Vs the alternatives

Most libraries pick a lane. We picked a different one.

This isn't a Cursor replacement. It isn't a Tamagui replacement either. It's the library you reach for when you want all three audiences in one repo.

plyxuishadcnRadixTamaguiRN Reusables
Web + React Nativesingle treeweb onlyweb onlyboth, with compilernative, web ports
Branded tokensaugmentableCSS varsn/atypednativewind
Icon systemregistry, typed nameslucide importsn/ayour ownyour own
First-party MCPyesnononono
Distributionnpm + copy-pastecopy-pastenpmnpm + compilercopy-paste
Theme remix sharingsoon (1.0)nononono

From zero to a styled screen

Five minutes. No build step, no compiler, no codegen.

plyxui is a regular npm install. No vendored copy-paste. No special bundler config. No nativewind setup.

01

Install

Pick the layers you need. Foundation is three packages.

npm install @plyxui/core @plyxui/styles @plyxui/primitives
02

Wrap

ThemeProvider once at the root. It picks up OS preference until the user toggles.

import { ThemeProvider } from "@plyxui/styles";

<ThemeProvider>
  <App />
</ThemeProvider>
03

Use a primitive

Polymorphic Box plus typed Text and Button covers the first 80% of any screen.

import { Box, Text, Button } from "@plyxui/primitives";

<Box surface="primary" padding="lg">
  <Text size="xl" weight="bold">Hello, plyxui.</Text>
  <Button>Get started</Button>
</Box>
04

Add icons + the rest

Register the seed pack at boot, augment names if you need autocomplete.

import { registerIcons } from "@plyxui/icons";
import { seedPack } from "@plyxui/icons/pack";

registerIcons(seedPack);

Where it's going

A roadmap, not a wishlist.

Everything in Shipping is in the current branch. Next items land before 1.0. Soon is the post-launch slate.

PhaseWhatStatus
ShippingTokens + theme + Box + Text + Stack + Flex + Input + Button (web + native)live
ShippingIcon registry + 20 seed icons + native variantlive
ShippingAppShell + Sidebar + ScreenContainerlive
ShippingRouter-agnostic Navigator (react-router + react-navigation adapters)live
ShippingModal + Dropdown (web first, native trailing)live
ShippingMDX docs sitelive
NextMCP server handlers + llms.txt at the docs root-
NextTooltip, Tabs, Toast, Drawer-
NextSandpack live previews per comp on the docs site-
SoonTheme remix backend + plyxui.dev/r/<short-id> sharing-
SoonSprite-sheet codegen for heavy icon users-
SoonTeam mode: shared remix workspaces-

FAQ

The questions people ask first.

Is this really cross-platform, or is it a web library with a native escape hatch?+

Single source tree, deliberate .ts / .native.ts splits per component. Metro resolves .native.tsx automatically. Web bundlers get the .tsx. Both share the same hooks, the same tokens, the same public API. The native variants aren't stubs; they're complete implementations using React Native's primitives.

How does the MCP server actually help?+

Coding agents like Cursor and Claude Code rely on scraping HTML or reading READMEs. That's lossy. The plyxui MCP exposes the component library as structured data: list_components, describe_component (props, variants, examples), install_component, lint_usage. The agent never guesses at a prop name.

Where does AI Polish fit in?+

AI Polish is a sibling project, not part of plyxui. It's a standalone desktop app that pairs nicely with the library: pick a project folder, paste your Anthropic key, hand the agent a Figma frame, every Write or Edit is held for Apply / Reject review. Lives at github.com/vineethpawar/ai-polish-desktop. You can use plyxui without it, and you can use it on any non-plyxui codebase.

What if I don't want the agent layer?+

Don't install @plyxui/mcp. The foundation packages have no agent code in them. The component library works without any of the agent-aware bits.

Why not just use Tamagui?+

Tamagui is fantastic at the cross-platform problem and the compiler model is impressive. plyxui bets on a simpler runtime (no compiler), a typed token model that's friendlier for agents, and a first-party MCP. Pick the one that fits your team. They aren't directly competing.

What does the remix layer cost?+

Free during the alpha. The remix backend will be hosted and the public sharing surface lands with 1.0. There will be a team tier with multi-user remix workspaces; the local + single-user flow stays free.

Can I use it on a closed-source repo?+

Yes. The library is MIT. The MCP server runs locally and never phones home.

When does 1.0 ship?+

The library 0.x track stabilizes through the next month. 1.0 lands when the docs are complete, the MCP handlers are real (not stubs), and the remix sharing surface is in beta. Targeting Q3 2026.

Free alpha. BYOK. macOS. Windows. Linux.

Stop rewriting components three times.

Install the foundation. Try one screen. Decide if the agent-aware bits are for you.

View on GitHubRead the docs