npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@moontra/moonui-pro

v4.28.0

Published

Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components

Downloads

11,629

Readme

MoonUI Pro 🌙✨

Premium React components for advanced web applications. MoonUI Pro extends the base MoonUI library with sophisticated, enterprise-grade components designed for complex use cases and professional applications.

npm version License: Commercial TypeScript

Two setups, both mandatory. Styling setup makes the components look right — skip it and they render shapeless and colourless. License setup makes them work — without a build-time license token, Pro components render a lock screen instead of their content.

✨ What's Included

A selection of what ships in the package. The full, always-current component list lives at moonui.dev/docs.

📊 Data & Analytics

  • DataTable — Enterprise table with search, faceted/quick filters, export, row selection, expandable rows and bulk actions
  • Table — Lower-level styled table primitives
  • AdvancedChart, ChartWidget — Data visualization built on Recharts
  • Timeline — Event timelines with rich content
  • Kanban — Drag-and-drop board layouts

✏️ Editors & Forms

  • RichTextEditor — WYSIWYG editor
  • FormWizard — Multi-step forms with validation and progress tracking
  • ColorPicker — Color selection

🎮 Interactive & Gesture

  • DraggableList — Sortable lists with smooth animations
  • SwipeableCard — Touch-friendly cards
  • GestureDrawer — Mobile-optimized drawer with gestures
  • VirtualList, SelectableVirtualList — High-performance virtualized lists
  • LazyList, AnimatedList — Lazy and animated list rendering

📅 Calendar

  • Calendar, AdvancedCalendar — Date selection and event calendars

🎨 Visual & Motion

  • BentoGrid — Modern bento-style layouts
  • Spotlight — Search and command launcher
  • ParallaxScroll, ScrollReveal — Scroll-driven effects
  • GridPattern, GridDistortion — Decorative backgrounds
  • Marquee, Meteors — Motion accents
  • LightboxProvider — Image lightbox

🔤 Text Effects

  • GlitchText, ShinyText, TextReveal, Text3D

🚀 Installation

npm install @moontra/moonui-pro @moontra/moonui

# Tailwind is required; the components also use the animate plugin
npm install -D tailwindcss tailwindcss-animate

Why @moontra/moonui is in that line. Pro ships its own React primitives (Button, Card, Badge, Input, …), so you do not need the free package for its components. You do need it for its design system: the only copy of the Tailwind preset and of the CSS variables the Pro components paint with lives there. Between its inline styles and its Tailwind classes, Pro needs 51 theme variables (--primary, --card, --secondary-500, --info-subtle, …) and defines none of them. Install Pro on its own and every bg-primary resolves to transparent and every text-foreground to plain black — see Styling setup.

The free package is MIT-licensed, and using its components is still optional.

🎨 Styling setup

All three steps are required. Skip step 1 and the utility classes are never generated; skip step 2 and they are generated but every colour resolves to nothing; skip step 3 and the Radix-driven enter/exit animations are missing.

1. Add the Tailwind preset

The preset maps Tailwind's colour, radius and animation scales onto MoonUI's CSS variables. The content entry for Pro's dist/** matters just as much: Tailwind only generates classes it can see, and the Pro component classes live inside the package bundle.

// tailwind.config.js  (Tailwind v3 config format)
module.exports = {
    presets: [require("@moontra/moonui/tailwind-preset")],
    content: [
        "./src/**/*.{js,ts,jsx,tsx,mdx}",
        "./node_modules/@moontra/moonui-pro/dist/**/*.{js,mjs}",
        // only if you also use the free components:
        "./node_modules/@moontra/moonui/dist/**/*.{js,mjs}",
    ],
    plugins: [require("tailwindcss-animate")],
};

If your package.json has "type": "module", name the file tailwind.config.cjs. Left as .js, Node parses it as ESM and the module.exports above throws ReferenceError: module is not defined before Tailwind ever sees your config.

There is no separate Pro preset — @moontra/moonui/tailwind-preset is a superset of everything Pro needs. It declares every colour key Pro uses (primary, secondary, success, warning, caution, error, info, destructive, muted, accent, card, popover, border, input, ring, background, foreground) plus brand/brand-accent, and it already sets darkMode: "class".

2. Import the design tokens

The preset only maps the variables; this file defines them, for both light and dark.

/* globals.css */
@import "@moontra/moonui/src/styles/tokens.css";

@tailwind base;
@tailwind components;
@tailwind utilities;

Which specifier, and why they differ. CSS @import and JavaScript import are resolved by different machinery, and the two want different strings:

| Where you write it | Specifier that works | |---|---| | CSS @import, Tailwind v3 + PostCSS (postcss-import) | @moontra/moonui/src/styles/tokens.css | | CSS @import, Vite (its resolver reads exports) | @moontra/moonui/tokens.css | | JavaScript import (Node / any bundler) | @moontra/moonui/tokens.css |

postcss-import does not read a package's exports map, so in that pipeline it needs the physical path (it ships in the tarball via the package files field). Vite and Node are the mirror image: they are exports-aware and reject the physical path. Both routes load the same file — pick one, not both.

// app/layout.tsx — the JavaScript route
import "@moontra/moonui/tokens.css";

Recommended: also add the semantic layer (shadow-xs, animate-fade-in, duration-fast, ease-bounce and the elevation/duration/easing tokens). Components render correctly without it — every variable the preset reads already lives in tokens.css.

@import "@moontra/moonui/src/styles/design-system.css";

3. Keep tailwindcss-animate in plugins

Pro's overlays (Dialog, Popover, Select, Toast, NavigationMenu, …) rely on animate-in, fade-in, slide-in-from-* and data-[state=open]: variants. They come from the tailwindcss-animate plugin, which the preset deliberately does not bundle so that the package cannot force a dependency on you. Without it those 25 classes are simply absent and the overlays pop in without transition.

Bringing your own theme

You are not obliged to use MoonUI's values — the preset reads variables, it does not hardcode colours. Override any of them after the import and Pro follows:

@import "@moontra/moonui/src/styles/tokens.css";

:root {
    --primary: 262 83% 58%;
}

What you cannot do is define nothing. If you skip tokens.css you must supply all 51 variables yourself, including MoonUI-specific families such as --secondary-500, --warning-700, --info-subtle and --brand-*.

🔐 License setup

Pro access is resolved at build time, not per request. The flow is:

MOONUI_LICENSE_KEY  ──►  postinstall.cjs  ──►  .moonui-license-token  ──►  withMoonUIProToken
   (build env)            (validates)          (base64 JSON)              (inlines into bundle)
                                                                                  │
                                                    MoonUIAuthProvider  ◄─────────┘
                                                    (reads it at runtime)

All three steps are required. Skip any one and every Pro component renders ProLockScreen.

1. Provide your license key at build time

# CI / Docker / any build environment
MOONUI_LICENSE_KEY=moonui_xxxxxxxxxxxx

MOONUI_LICENSE_KEY is the canonical name. NEXT_PUBLIC_MOONUI_LICENSE_KEY, VITE_MOONUI_LICENSE_KEY and REACT_APP_MOONUI_LICENSE_KEY are also accepted as fallbacks.

2. Generate the token before the build

Package managers skip lifecycle scripts in many CI setups, so run the token generator explicitly:

{
  "scripts": {
    "prebuild": "node node_modules/@moontra/moonui-pro/scripts/postinstall.cjs",
    "build": "next build"
  }
}

3. Inline the token and mount the provider

Next.js — wrap your config:

// next.config.mjs
import { withMoonUIProToken } from '@moontra/moonui-pro/next-config';

export default withMoonUIProToken({
  // ...your Next.js config
});

Vite — add the plugin:

// vite.config.js
import moonUIProPlugin from '@moontra/moonui-pro/vite';

export default {
  plugins: [moonUIProPlugin()],
};

Then wrap your app once, at the root:

// app/layout.tsx
import { MoonUIAuthProvider } from '@moontra/moonui-pro';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <MoonUIAuthProvider>{children}</MoonUIAuthProvider>
      </body>
    </html>
  );
}

MoonUIAuthProvider takes no licenseKey prop — it reads the token that step 2 and 3 produced.

⚠️ Without the provider, hasProAccess is always false. useMoonUIAuth() does not throw when no provider is mounted; it silently returns a free-plan state. That is the single most common cause of "my license is valid but everything is locked".

Deploying

The token is written the same way on every platform — Vercel, Netlify, Docker, Kubernetes, Dokploy, or a bare server. Just make sure MOONUI_LICENSE_KEY is present during the build, not only at runtime.

ARG MOONUI_LICENSE_KEY
ENV MOONUI_LICENSE_KEY=$MOONUI_LICENSE_KEY
RUN npm run build

Self-hosted gotcha: if you build with NODE_ENV=production, npm skips devDependencies. Keep autoprefixer, tailwindcss and postcss in dependencies, or the build fails before the token ever matters.

Full deployment matrix: moonui.dev/docs/authentication

🧩 Usage

import { MoonUIAuthProvider, DataTable, RichTextEditor, Card } from '@moontra/moonui-pro';

function App() {
  const data = [
    { id: 1, name: 'John', email: '[email protected]' },
    { id: 2, name: 'Jane', email: '[email protected]' },
  ];

  const columns = [
    { accessorKey: 'name', header: 'Name' },
    { accessorKey: 'email', header: 'Email' },
  ];

  return (
    <MoonUIAuthProvider>
      <Card className="p-6">
        <h1 className="text-2xl font-bold mb-4">MoonUI Pro Demo</h1>

        <DataTable data={data} columns={columns} searchable pagination />

        <RichTextEditor placeholder="Start writing..." className="mt-4" />
      </Card>
    </MoonUIAuthProvider>
  );
}

📊 DataTable

DataTable is built on TanStack Table v8. Column definitions are standard ColumnDef objects.

<DataTable
  data={data}
  columns={columns}
  searchable
  filterable
  selectable
  pagination
  pageSize={25}
  exportable={{ formats: ['csv', 'json'], filename: 'users' }}
  onRowSelect={(rows) => console.log(rows)}
/>

Feature flags

features groups the table's optional capabilities:

<DataTable
  data={data}
  columns={columns}
  features={{
    sorting: true,
    filtering: true,
    pagination: true,
    search: true,
    columnVisibility: true,
    rowSelection: true,
    density: true,
    export: ['csv', 'json'],
  }}
/>

Quick filters

Dropdown filters, optionally auto-detecting their options from the data:

<DataTable
  data={data}
  columns={columns}
  quickFilters={[
    { column: 'status', label: 'Status', options: 'auto', showCounts: true },
    { column: 'department', label: 'Department', multi: true },
  ]}
/>

Faceted filters

Checkbox filters with counts:

<DataTable data={data} columns={columns} facetedFilters={['category', 'tags']} />

Filtering custom-rendered cells

When a cell renders a component, tell the filter where the raw value lives:

const columns = [
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => <Badge>{row.getValue('status')}</Badge>,
    meta: {
      filterType: 'select',
      filterOptions: ['Active', 'Pending', 'Completed'],
      filterValueAccessor: (row) => row.status,
    },
  },
];

Expandable rows

<DataTable
  data={data}
  columns={columns}
  enableExpandable
  renderSubComponent={({ row }) => <pre>{JSON.stringify(row.original, null, 2)}</pre>}
/>

🎨 What the bundle does and does not ship

Setup lives in Styling setup; this section is about why it is needed.

Injected by the JavaScript bundle. The ESM build inlines the eight stylesheets its components import — nprogress, meteors, aurora-background, slash-commands, table-styles, timeline, plus react-grid-layout and react-resizable from their own packages — and appends them to <head> on import. Nothing to do on your side.

Not injected, and this is the part people miss. Those eight files are component CSS. They are not the design system:

  • Utility classes are not shipped. Every Pro component styles itself with Tailwind classes (bg-primary, border-border, text-muted-foreground). Those rules are generated by your Tailwind build, which is why your content globs must include node_modules/@moontra/moonui-pro/dist/**.
  • Token values are not shipped. dist/index.mjs reads 14 theme variables directly in inline styles, and the utility rules Tailwind generates from its class names pull in the rest — 51 in total. The bundle defines zero of them. They come from @moontra/moonui's tokens.css (or from your own equivalent).

There is no @moontra/moonui-pro/styles.css entry point — importing one fails, and there is no published Pro stylesheet that would define tokens for the npm route.

The CDN build is the one exception to both rules: it does not inject, and it ships a companion dist/cdn/index.css that does define the tokens — a CDN page has no Tailwind build and no way to pull @moontra/moonui's tokens.css, so that one file has to be enough on its own. See CDN / no-build usage.

MoonUI Pro follows the base MoonUI theming system: HSL triplets in CSS variables and a .dark class for dark mode — the same system @moontra/moonui uses, from the same file.

🌐 CDN / no-build usage

MoonUI Pro runs from a plain HTML page, with no bundler and no npm install.

React must come from the page, never from the MoonUI Pro bundle. Until 4.20.0 the CDN build bundled React; a CDN page has to load its own React too, so the page ended up with two copies, the hook dispatcher was null, and every component using a hook threw Cannot read properties of null. That was the substance of issue #410. The current build externalizes React — measured as a controlled experiment on the base package: React inside the bundle crashed 7 of 7 component scenarios, React outside passed 7 of 7.

Route A — esm.sh (zero setup, works today)

Works against the published package, no build required:

<script type="importmap">
{
  "imports": {
    "react":      "https://esm.sh/[email protected]",
    "react/":     "https://esm.sh/[email protected]/",
    "react-dom":  "https://esm.sh/[email protected]",
    "react-dom/": "https://esm.sh/[email protected]/",
    "next-themes": "https://esm.sh/[email protected]?external=react,react-dom&target=es2022",
    "@moontra/moonui-pro": "https://esm.sh/@moontra/[email protected]?bundle&external=react,react-dom&target=es2022"
  }
}
</script>

All three query parameters are mandatory, and for Pro one of them is fatal rather than merely wasteful:

| Parameter | Drop it and… | |---|---| | external=react,react-dom | esm.sh resolves the peer range itself and loads a React independent of your importmap. Every hook-using component crashes. | | bundle | Pro does not load at all. Pro's module graph contains a CSS side-effect import (react-grid-layout/css/styles.css); in per-module mode esm.sh leaves it as a CSS URL and the browser refuses it — "Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of text/css" — killing the entire graph with no pageerror at all. Measured across four independent runs: the graph never finished in 300 s. | | target=es2022 | The response carries vary: User-Agent, so the output depends on the browser asking. |

esm.sh is a third party and is not covered by any MoonUI SLA. For a paid product this is a real trade-off: the license gate's code would live inside a bundle built by someone else's pipeline. It is not a secrecy risk — the package is public on npm and the compiled source has always been downloadable — it is a continuity and determinism risk. Route B exists so the artifact that enforces the gate is ours.

Route B — MoonUI Pro's own CDN artifacts

Not published yet. These files are produced by this repository's build but ship with the next release. The URLs below show the shape they will take, not links that resolve today. The dist/cdn/index.global.js published in 4.20.0 and earlier is the old, React-bundled build described above — do not use it.

| File | Format | Global | React support | |---|---|---|---| | dist/cdn/index.global.js | IIFE | window.MoonUIPro | React 18 only | | dist/cdn/index.esm.js | ESM + importmap | — | React 18 and 19 | | dist/cdn/index.css | stylesheet | — | both |

unpkg and jsdelivr in package.json point at the IIFE build.

Why two formats: the IIFE build reads React off window.React, which requires React's UMD build — and React 19 publishes no UMD build. On React 19 the ESM file is the only option. That is where React left the UMD format, not a MoonUI limitation.

<!-- React 18, IIFE -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@moontra/moonui-pro/dist/cdn/index.css">
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@moontra/moonui-pro/dist/cdn/index.global.js"></script>
<script>
  const { MoonUIAuthProvider, GradientText } = window.MoonUIPro;
  ReactDOM.createRoot(document.getElementById("root")).render(
    React.createElement(MoonUIAuthProvider, null,
      React.createElement(GradientText, null, "Hello"))
  );
</script>

One stylesheet is enough. Unlike the npm route, index.css ships the design tokens as well as the utilities — a CDN page has no Tailwind build to generate them and no way to reach @moontra/moonui's tokens.css.

Verified in a real browser against the produced artifacts — IIFE + React 18, ESM + React 18, ESM + React 19: 690 exports, 5 of 5 cases rendered, zero crashes, zero page errors. Reproduce with npm run verify:cdn inside packages/moonui-pro.

Licensing on a CDN page

The license gate works on the CDN and it is fail-closed. Measured in all three loader configurations with no license present: across 120 sampled animation frames, the real Pro content appeared in zero of them; components render ProLockScreen instead.

A license can be granted at runtime, but today there is exactly one way and it is not a product:

// Development only. Not a supported distribution mechanism.
localStorage.setItem("moonui_license_token", JSON.stringify(tokenPayload));

With that token present, the same measurement flips: real Pro content in 119 of 120 frames (IIFE + React 18) and 117 of 120 (ESM + React 19).

The intended flow — passing a key via a data-moonui-license script attribute and validating it against the origin server — is designed but not implemented. Until it lands, treat CDN usage of Pro as prototyping.

Measurement caveat for anyone re-running this: if the MoonUI CLI auth server is running on localhost:7878, the provider will ask it and silently grant Pro access to "unlicensed" pages. An earlier measurement was invalidated exactly this way (117 of 120 frames of fake Pro content). scripts/cdn/verify-cdn.mjs aborts that request; an internet CDN consumer has no such server.

Styling limits and browser support

index.css is generated by scanning MoonUI Pro's own source, so it contains the classes Pro components use and nothing else. Your own utility classes — mt-[37px], text-[13px] — are not in it. Add Tailwind Play CDN alongside it (Tailwind marks Play CDN as not for production: browser-side compilation, FOUC, Tailwind v3, third external dependency), or use inline styles.

<script type="importmap"> requires Chrome/Edge 89+, Safari 16.4+, Firefox 108+ (per MDN/caniuse; not measured here). Older browsers need a polyfill such as es-module-shims, which MoonUI has not tested.

⚡ Performance

  • VirtualizationVirtualList, SelectableVirtualList for large collections
  • Lazy renderingLazyList defers offscreen work
  • Tree shaking — ESM-only build; import only what you use
import { VirtualList } from '@moontra/moonui-pro';

<VirtualList
  items={thousandsOfItems}
  itemHeight={50}
  renderItem={({ item, index }) => <div key={item.id}>Row {index}: {item.name}</div>}
/>

📱 Mobile & Touch

import { SwipeableCard, GestureDrawer } from '@moontra/moonui-pro';

<SwipeableCard onSwipeLeft={handleSwipeLeft} onSwipeRight={handleSwipeRight}>
  <CardContent />
</SwipeableCard>

📦 Package Details

  • Format: ESM only (dist/index.mjs, 2.53 MiB unminified in 4.19.2), component styles injected by JS
  • CDN: two minified bundles — dist/cdn/index.global.js (IIFE, 2.98 MiB, global name MoonUIPro) and dist/cdn/index.esm.js (ESM, 2.96 MiB) — plus dist/cdn/index.css (208 KB, 31 KB gzipped: component styles, utilities and design tokens). React is not bundled in either; see CDN / no-build usage
  • Types: full TypeScript definitions included
  • Peer dependencies (declared): React 18+ or 19, React DOM, next-themes
  • Also required, not declared as peers: Tailwind CSS v3 and tailwindcss-animate at build time, and @moontra/moonui for the preset and design tokens — see Styling setup
  • Built on: TanStack Table v8, Recharts, Framer Motion

The CDN bundle has no build step, so it cannot receive a build-time license token. Without one, Pro components render their lock screen — verified fail-closed, with the real Pro content never appearing in any of 120 sampled frames. A license can be supplied at runtime, but only by writing moonui_license_token into localStorage by hand; that is not a productized flow. See CDN / no-build usage.

🔒 License & Privacy

  • A valid license key is required for production builds; development works without one
  • The license key is validated once at build time against moonui.dev
  • No telemetry. The package does not phone home at runtime and does not transmit your domain
  • The published bundle is plain, readable ESM — it is licensed, not obfuscated

💳 Pricing

MoonUI Pro is a one-time purchase. There is no subscription.

| Plan | Price | Includes | |------|-------|----------| | Professional | $79 one-time | 1 device, 100+ Pro components, lifetime updates | | Team | $199 one-time | 3 developer licenses | | Enterprise | $499 one-time | Unlimited devices, white-label |

View pricing →

🛠️ Development

git clone https://github.com/oguzhanayyldz/moonui
cd moonui/packages/moonui-pro
npm install

npm run dev     # watch build
npm run build   # production build
npm run test    # jest
npm run lint    # eslint

🔗 Ecosystem

📚 Documentation & Support

📄 License

Licensed under a Commercial License. See LICENSE for details.

  • Valid license key required for production use
  • Development usage allowed without a license
  • License includes updates and support
  • Licensed per device/developer — see the pricing table above

WebsiteDocumentationPricing

Built with ❤️ for developers who demand excellence