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.
Why this exists
After shipping a few production apps on top of shadcn + Radix + bespoke Electron chrome, the same gaps showed up every time.
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.
Big design systems lose autocomplete on token names, variants, and icons. plyxui tokens are interfaces, augmentable from userland. Names extend; types follow.
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
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.
@plyxui/core, @plyxui/styles, @plyxui/primitives. Tokens, theming, Box, Text, Stack, Flex, Input, Button. Cross-platform.
@plyxui/icons, @plyxui/comps, @plyxui/layouts. The icon registry, Modal, Dropdown, AppShell, Sidebar, ScreenContainer.
@plyxui/mcp gives coding agents a structured handle on the library. List, describe, install, lint. No HTML scraping.
What's in the box
Each of these is shipping in the alpha. Not the roadmap.
Tokens are interfaces, not enums. Augment from userland; the rest of the library autocompletes against your brand.
as=button, as=a, as=anything. Native attributes type-check. Works exactly as you expect.
Metro picks native, Webpack/Vite/Next/Electron pick web. Same public API, sane platform-specific internals.
Names autocomplete, names extend. Built around a typed registry, not per-file imports.
defineRoutes() once, render with the react-router or react-navigation adapter. Same routes table powers Sidebar + tabs.
AppShell, Sidebar, ScreenContainer. No router opinion. Drop in anywhere.
Web uses the native <dialog>. Dropdown is keyboard-aware. Native ports trail by a small margin and are catching up fast.
@plyxui/mcp gives coding agents a structured handle on the library. List, search, install, lint without scraping HTML.
ThemeProvider follows prefers-color-scheme until the user explicitly picks. Then it stops listening, by design.
Under the hood
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
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.
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.
class-variance-authority handles className composition. Small, no compiler, drops out of the way the moment a consumer wants their own CSS.
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
Coding agents talk to plyxui through a structured protocol instead of scraping HTML docs. The library and the agent pull from the same source.
The remix layer
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.
{
"name": "Warm October",
"tokens": {
"primaryOrange": { "light": "#FF7A30", "dark": "#FFA260" },
"primaryFill": { "light": "#FFF7EE", "dark": "#1A0F08" }
},
"overrides": {
"Button": { "primary": { "borderRadius": "pill" } }
}
}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
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.
| plyxui | shadcn | Radix | Tamagui | RN Reusables | |
|---|---|---|---|---|---|
| Web + React Native | single tree | web only | web only | both, with compiler | native, web ports |
| Branded tokens | augmentable | CSS vars | n/a | typed | nativewind |
| Icon system | registry, typed names | lucide imports | n/a | your own | your own |
| First-party MCP | yes | no | no | no | no |
| Distribution | npm + copy-paste | copy-paste | npm | npm + compiler | copy-paste |
| Theme remix sharing | soon (1.0) | no | no | no | no |
From zero to a styled screen
plyxui is a regular npm install. No vendored copy-paste. No special bundler config. No nativewind setup.
Pick the layers you need. Foundation is three packages.
npm install @plyxui/core @plyxui/styles @plyxui/primitives
ThemeProvider once at the root. It picks up OS preference until the user toggles.
import { ThemeProvider } from "@plyxui/styles";
<ThemeProvider>
<App />
</ThemeProvider>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>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
Everything in Shipping is in the current branch. Next items land before 1.0. Soon is the post-launch slate.
| Phase | What | Status |
|---|---|---|
| Shipping | Tokens + theme + Box + Text + Stack + Flex + Input + Button (web + native) | live |
| Shipping | Icon registry + 20 seed icons + native variant | live |
| Shipping | AppShell + Sidebar + ScreenContainer | live |
| Shipping | Router-agnostic Navigator (react-router + react-navigation adapters) | live |
| Shipping | Modal + Dropdown (web first, native trailing) | live |
| Shipping | MDX docs site | live |
| Next | MCP server handlers + llms.txt at the docs root | - |
| Next | Tooltip, Tabs, Toast, Drawer | - |
| Next | Sandpack live previews per comp on the docs site | - |
| Soon | Theme remix backend + plyxui.dev/r/<short-id> sharing | - |
| Soon | Sprite-sheet codegen for heavy icon users | - |
| Soon | Team mode: shared remix workspaces | - |
FAQ
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.
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.
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.
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.
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.
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.
Yes. The library is MIT. The MCP server runs locally and never phones home.
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.