# Cosmic UI: a sci-fi component library on zag-js state machines and Tailwind

> Cosmic UI is a sci-fi themed React component library and its documentation site, built in Astro with React islands for the interactive parts, where most components are thin wrappers around @zag-js state machines plus a custom SVG decoration system called Frame. It is private, unlicensed and still a working repository rather than a published package, so it is a reference implementation to read and copy from rather than a dependency to install.

**rizznme/cosmic-ui** — A collection of Sci-Fi themed components and futuristic design elements for modern web applications.

- Repository: https://github.com/rizznme/cosmic-ui
- Website: https://cosmic-ui.com
- Stars: 759 · Forks: 62
- Language: Astro
- License: not declared
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/rizznme-cosmic-ui

## A docs site that is also the component library

Cosmic UI describes itself as a sci-fi themed React component library and docs site, and the interesting part is that those are the same repository rather than two. The component source, the documentation, the interactive previews and the navigation all live together.

The project was ported from an original Vite plus React single page application to Astro with static output and React islands for the interactive parts. That migration is visible in the folder structure, which separates the four kinds of file. There is src/components/ui/ for the library itself, src/components/docs/ for shared doc page building blocks such as Wrapper, Title, Preview tabs, PreviewCode, InstallPackage and the table of contents Menu, src/components/pages/ with one file per route's actual content mounted as a React island, and src/components/SiteChrome.tsx for the header navigation and mobile sidebar drawer.

The site is at cosmic-ui.com, the primary language is Astro, and the topic list covers components, frontend, tailwindcss and design-system, so the intent is a design system rather than a demo site.

One thing to note early: the package is marked private with version 0.1.0 and there are no GitHub releases, so this is a repository you read, not a package you install.

## The UI layer is mostly zag-js wrappers plus Frame decoration

The component list in src/components/ui/ is Button, Dialog, Menu, Combobox, Toast, Tabs, Accordion, Alert, Checkbox, RadioGroup, Switch, Input, Textarea, Chart and Frame. The documentation describes these as mostly thin wrappers around @zag-js state machines, plus a custom Frame SVG decoration system.

That is the core architectural decision, and it is a good one to understand before reading any component. Zag-js supplies the behaviour, that is the state machine handling keyboard interaction, focus management, the open and closed states of a dialog or a menu, and it does so in a framework agnostic way. The cosmic-ui components then add the visual layer on top, which is where the sci-fi styling and the Frame decoration live.

The consequence for a reader is that the interesting logic is not in this repository. A Dialog component here is mostly a matter of wiring zag-js into a styled shell, so the state machine behaviour you inherit is the behaviour of the @zag-js package version you depend on. The version list in the manifest pins the whole family to the 1.43.3 series, from accordion and avatar through dialog, menu, number-input, pagination, presence, radio-group, select, switch, tabs and toast.

Frame is the piece that is genuinely this project's own, and it is the one to study.

## Frame is the only original visual system in the library

Everything else in the UI directory delegates behaviour to zag-js, but Frame is described as a custom SVG decoration system, and it is the component that makes the library look the way it does rather than looking like a restyled headless set.

The name suggests the role. A frame is the chrome around a control, the panel outline, the corner brackets, the ornamental lines and shapes that sell the science fiction aesthetic. Decoration of that kind is normally done with background images, pseudo-element borders or absolutely positioned SVG, and all three have the same problem: they scale badly, they break at unusual sizes, and they cannot respond to component state.

Putting the decoration in a React component with a Frame directory alongside the behaviour components means the ornament is composed in the same tree as the thing it decorates, and the same variant system can drive it. There is also a dependency that hints at how the SVG is handled: @left4code/svg-renderer is present, alongside a package whose name is a direct reference to the rendered output.

A caveat worth stating: the repository documentation does not explain the Frame API, so anyone adopting the pattern is reading the component source rather than following a written contract.

## Running the dev server and producing the static build

The development workflow is the standard Astro one. Install the dependencies and start the dev server:

```bash
npm install
npm run dev
```

The production path builds the static output and then serves it locally so you can check the result:

```bash
npm run build
npm run preview
```

The scripts in the manifest show what is actually happening. The dev script is astro dev, the preview script is astro preview, and the build script is astro check followed by astro build. That ordering is worth noticing, because astro check runs the TypeScript and template checks before the build, so type errors fail the build rather than surfacing as broken pages. The @astrojs/check package and the tsconfig.json at the root are what make that possible.

Astro is pinned at ^7.2.0 with @astrojs/react at ^6.0.2, and the content search is handled by astro-pagefind, which builds a static search index from the built output rather than querying a server.

The site is a static output with React islands, so the interactive components hydrate individually and the rest of each page ships as HTML. The build command emits a directory you can put on any static host.

## A four step checklist for adding a component

The documentation is unusually concrete about how to extend the library, and the workflow is a good template for any component library built this way.

First, add the component itself at src/components/ui/<name>.tsx, using the @zag-js packages plus Frame plus cva and twMerge, matching the style of the existing components. Second, add the doc content to src/components/pages/<name>.tsx, copying an existing one as a template with Preview, Installation and Usage sections. Third, add the route as src/pages/docs/<name>.astro, rendering the docs layout with the page component mounted as a client:load island. Fourth, add a nav link in the docLinks array in src/components/SiteChrome.tsx.

```
3. Add the route: `src/pages/docs/<name>.astro`, rendering
   `<DocsLayout><YourPage client:load /></DocsLayout>`.
4. Add a nav link in `src/components/SiteChrome.tsx`'s `docLinks`.
```

The order matters because each step depends on the previous one, and step four is the one people forget, since a component can render perfectly and still be unreachable from the navigation.

The use of client:load on every page is also a design decision worth noting. It means every docs page hydrates the whole React tree for that page, which is more JavaScript than a purely static page would need, in exchange for a uniform authoring model where every page is a React island.

## Both React and Vue are installed, and only React is used

The dependency list contains two parallel stacks. There is @astrojs/react with react and react-dom at version 19, and there is @astrojs/vue with vue at ^3.5.41, plus both @zag-js/react and @zag-js/vue at 1.43.3, and both lucide-react and @lucide/vue for icons.

Yet the documentation describes the pages as React islands and the whole site structure is built around React components, and the topics list names react rather than vue. So the Vue packages appear to be residue from a planned or partial multi-framework support rather than something the current code uses.

That matters for anyone who copies this package.json as a starting point. You would be installing two icon libraries, two zag-js bindings and two framework integrations, and paying the install size and maintenance attention for a Vue path that the current site does not exercise.

The variant handling is the other pattern to copy. The component recipe uses cva, class-variance-authority, alongside tailwind-merge, with tw-animate-css and Tailwind 4.3.3 through the @tailwindcss/vite plugin. The combination is a standard way to define a component with typed variants and let conflicting Tailwind classes resolve to the last one specified rather than the first.

## Licence, environment configuration and the maintenance picture

The licence is unstated, and there is no LICENSE file in the top level entries. That is a hard stop for anyone planning to copy the code into a product, because without an explicit grant the default is that the author retains all rights. A visual style can be imitated, but the Frame component and the component source cannot be lifted into another project on the strength of a public repository alone.

The environment configuration is a small file but tells you what the site depends on in production. The .env.example sets PUBLIC_CF_BEACON_TOKEN for Cloudflare Web Analytics, described as adding a site with no DNS change needed, and two ConvertKit values, PUBLIC_CONVERTKIT_FORM_ID and PUBLIC_CONVERTKIT_API_KEY, for a newsletter form. The comments record the exact path through each dashboard, including the note that the ConvertKit key is the public one and not the API Secret. The PUBLIC_ prefix is what lets these reach the client bundle.

On maintenance, the last push was on 2026-09-07 and the repository is not archived, but that is more than six months before today, so treat the code as a snapshot rather than something that receives regular attention. There are no GitHub releases, the version field is 0.1.0, and the repository is private in the npm sense, so the sensible use is to read it.

## Conclusion

Adopt Cosmic UI as a reference for how to structure a headless state machine component library, particularly the combination of @zag-js behaviour, cva and twMerge variant handling, and a separate SVG decoration layer, and copy the four step workflow for adding a component. Do not adopt it as an installed dependency, since the package is private, the version is 0.1.0, there are no GitHub releases and the licence is unstated, so there is nothing to depend on and nothing permitting redistribution. Before you build on its code, check the licence position with the maintainer, because a repository with no licence file grants no rights to copy from, and confirm the @zag-js version range you want, since the package pins the 1.43.3 series and the behaviour of those state machines is the substance of every component here.

## FAQ

### What is Cosmic UI and what is it built on?

Cosmic UI is a sci-fi themed React component library and documentation site, ported from a Vite plus React SPA to Astro with static output and React islands for interactive parts. Its components are mostly thin wrappers around @zag-js state machines, with Tailwind and a custom Frame SVG decoration system for the visuals.

### How do I run the Cosmic UI docs site locally?

Run npm install followed by npm run dev for the development server, and npm run build followed by npm run preview for the static build. The build script runs astro check before astro build, so TypeScript and template errors fail the build rather than shipping.

### How do I add a new component to Cosmic UI?

Four steps: add the component at src/components/ui/<name>.tsx using @zag-js, Frame, cva and twMerge, add its doc page to src/components/pages/<name>.tsx, add the route src/pages/docs/<name>.astro rendering <DocsLayout><YourPage client:load /></DocsLayout>, and add a nav link to the docLinks list in src/components/SiteChrome.tsx.

### What is the Frame component in Cosmic UI?

Frame is the custom SVG decoration system that Cosmic UI adds on top of the zag-js behaviour wrappers, and it is the one part of the library that is not a thin wrapper around an external package. The repository documentation does not describe its API, so it has to be read from the component source.

### Can I install Cosmic UI from npm?

No. The package is marked private with version 0.1.0 and the repository has no GitHub releases, so it is not distributed as a published package. The repository also states no licence, so check with the maintainer before copying any of the source.

## Sources

- [Issues](https://github.com/rizznme/cosmic-ui/issues)
- [Project website](https://cosmic-ui.com)
- [README](https://github.com/rizznme/cosmic-ui/blob/main/README.md)
- [rizznme/cosmic-ui on GitHub](https://github.com/rizznme/cosmic-ui)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rizznme-cosmic-ui
