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

@dg-ui-react/react

v0.5.0

Published

Damn Good UI — production-ready React component library

Downloads

393

Readme

@dg-ui-react/react

April 2026 — Hey everyone — the package is fully usable right now, the components work great and the DG Motion engine is solid, but I want to be upfront: things are moving fast. I'm pushing dozens of commits every single day — new themes, a completely custom animation engine that replaces framer-motion and GSAP, physics, text animation, SVG morphing, and a lot more. If something looks different between versions that's why. Stick around — what's coming is worth the wait. Thanks for checking it out. — AahPlexX

Damn Good UI — A production-ready React component library with 15 design themes, 1,478+ component exports, and a built-in zero-dependency motion system.

npm version license TypeScript React Tailwind CSS

Built with TypeScript 6 and Tailwind CSS v4. No external animation dependencies — all motion is powered by the built-in DG Motion engine.


Preview

Live showcase and documentation: dg-ui.com


Quick Start

npm install @dg-ui-react/react
// 1. Import the stylesheet once at your app root
import '@dg-ui-react/react/styles.css';

// 2. Import components from any theme
import { Button, Card, Input } from '@dg-ui-react/react/obsidian';

// 3. Use them
export default function App() {
  return (
    <Card>
      <Input placeholder="Enter your name" />
      <Button variant="primary">Submit</Button>
    </Card>
  );
}

No Tailwind configuration required — the library ships a single pre-compiled CSS file.


Installation

# npm
npm install @dg-ui-react/react

# pnpm
pnpm add @dg-ui-react/react

# yarn
yarn add @dg-ui-react/react

# bun
bun add @dg-ui-react/react

Peer Dependencies

| Package | Required Version | | ------------ | ---------------- | | react | >= 19.0.0 | | react-dom | >= 19.0.0 |

No animation peer dependency required. DG Motion ships bundled and zero-dependency.

Setup

Import the stylesheet once at the root of your application:

// app root (e.g. main.tsx, _app.tsx, layout.tsx)
import '@dg-ui-react/react/styles.css';

No Tailwind config, no PostCSS plugins, no build-step changes.


Themes

DG-UI ships 15 distinct design themes, each published as its own tree-shakeable subpath entry point. Every theme provides a complete, internally-consistent component set with full TypeScript declarations.

| Theme | Import Path | Components | Design Language | | --------------------- | -------------------------------- | :--------: | ----------------------------------------------------------------------------------------------------------------------------------- | | Obsidian | @dg-ui-react/react/obsidian | 127 | Dark developer-tools aesthetic — command palettes, data tables, code blocks, and full dashboard primitives | | Aurora | @dg-ui-react/react/aurora | 133 | Light SaaS-clean — pricing cards, avatar stacks, notification bells, and product-marketing surfaces | | Forge | @dg-ui-react/react/forge | 130 | Dark industrial warmth — gradient buttons, metric cards, and data-heavy analytics admin surfaces | | Mobile | @dg-ui-react/react/mobile | 129 | Touch-first native feel — bottom sheets, swipe actions, and mobile interaction patterns | | Neon | @dg-ui-react/react/neon | 106 | Cyberpunk glow — vivid green accents on dark backgrounds with glowing borders | | Vapor | @dg-ui-react/react/vapor | 119 | Glassmorphic ethereal — translucent frosted-glass surfaces with layered purple depth | | Fluid | @dg-ui-react/react/fluid | 149 | Motion-first declarative — 149 interactive components built on a unified animation primitive | | Retro 70s | @dg-ui-react/react/retro | 147 | Disco-era warmth — amber and earth-tone palette, sunset and earth modes, organic card surfaces | | Cinder | @dg-ui-react/react/cinder | 126 | Warm ember-toned dark — amber and rust accent palette for atmospheric dashboards | | Dusk | @dg-ui-react/react/dusk | 126 | Twilight enterprise — muted teal and blue-grey for professional presentation surfaces | | Scholar | @dg-ui-react/react/scholar | 135 | Education-focused — quiz cards, flashcard decks, lesson planners, grade displays, and 101 standard UI components | | Corporate | @dg-ui-react/react/corporate | 21 | Enterprise professional — clean, precise components for business applications | | Glass | @dg-ui-react/react/glass | 10 | Frosted glass surfaces — backdrop blur, translucent panels, and glassy depth | | Memphis | @dg-ui-react/react/memphis | 10 | 80s geometric pop — bold black shadows, pastel fills, and playful asymmetry | | Bio-Organic | @dg-ui-react/react/bio-organic | 50 | Bioluminescent living UI — organic shapes, pulsing glows, and flowing forms |

Motion System is also published at @dg-ui-react/react/motion — see the Motion System section below.


Import Patterns

DG-UI supports three import patterns.

Pattern 1: Subpath Imports (Recommended)

Best tree-shaking, unambiguous component origin. The recommended approach for production applications.

import { Button, Input, Card } from '@dg-ui-react/react/obsidian';
import { PricingCard, Badge } from '@dg-ui-react/react/aurora';
import { MetricCard } from '@dg-ui-react/react/forge';
import { QuizCard, FlashcardDeck } from '@dg-ui-react/react/scholar';
import { Button } from '@dg-ui-react/react/retro';

// TypeScript types
import type { ButtonProps, InputProps } from '@dg-ui-react/react/obsidian';

Pattern 2: Namespace Imports

For multi-theme applications where the same component name appears across themes.

import { Obsidian, Aurora, Scholar, Neon, Retro } from '@dg-ui-react/react';

<Obsidian.Button variant="primary">Dashboard</Obsidian.Button>
<Aurora.PricingCard tier={tier} />
<Scholar.QuizCard questions={questions} />
<Neon.Card>Cyberpunk content</Neon.Card>
<Retro.Button palette="sunset">Retro action</Retro.Button>

All 15 themes are available as namespaces: Obsidian, Aurora, Forge, Mobile, Neon, Vapor, Fluid, Retro, Cinder, Dusk, Scholar, Corporate, Glass, Memphis, BioOrganic.

Pattern 3: Motion Subpath Imports

import {
  Motion,
  MotionProvider,
  useMotionPreset,
  useGesture,
  useDrag,
  useScrollTrigger,
  useTimeline,
} from '@dg-ui-react/react/motion';

The root package @dg-ui-react/react exports theme namespaces, cn, and DgMotion. Flat component imports from the root are not supported — use subpath or namespace imports.

What Not to Do

// Wrong — components are not exported flat from the root
import { Button, Card } from '@dg-ui-react/react';

// Correct
import { Button } from '@dg-ui-react/react/obsidian';
// or
import { Obsidian } from '@dg-ui-react/react';
<Obsidian.Button />

Motion System

DG Motion is a zero-dependency animation engine built directly into @dg-ui-react/react. It is available at @dg-ui-react/react/motion and covers the full spectrum from declarative components to imperative timelines, physics, text animation, SVG morphing, scroll-linked animation, and a first-party Tailwind CSS plugin — all with automatic prefers-reduced-motion support.

No external dependencies. DG Motion replaces framer-motion, GSAP, tailwindcss-animate, and tailwindcss-motion with a unified, bundled-in engine.

Declarative Animation

import { Motion, MotionPresence, MotionProvider } from '@dg-ui-react/react/motion';

// Wrap any content with a preset animation
<Motion preset="fadeInUp" duration="normal">
  <Card>Animated content</Card>
</Motion>

// Animate enter/exit with presence detection
<MotionPresence>
  {isVisible && (
    <Motion preset="scaleIn">
      <Dialog>Modal content</Dialog>
    </Motion>
  )}
</MotionPresence>

// Stagger children
<StaggerContainer staggerDelay={0.05}>
  {items.map(item => (
    <StaggerItem key={item.id} preset="fadeInUp">
      <ListItem>{item.name}</ListItem>
    </StaggerItem>
  ))}
</StaggerContainer>

Imperative Animation & Timelines

import { animate, timeline, useAnimate } from '@dg-ui-react/react/motion';

// Tween any element imperatively
animate('#hero', { opacity: 1, y: 0 }, { duration: 0.4, ease: 'easeOut' });

// Animate with a Promise
await animate(ref.current, { x: 200 }, { duration: 0.3 });

// Build a timeline with relative positions
const tl = timeline();
tl.to('#backdrop', { opacity: 1 }, 0)
  .to('#panel', { y: 0 }, '+=0.05')
  .to('#content', { opacity: 1 }, '<0.1')
  .play();

// Scoped imperative hook (auto-cleans up on unmount)
function MyComponent() {
  const [scope, animate] = useAnimate();
  return (
    <div ref={scope}>
      <button onClick={() => animate('li', { opacity: 1, x: 0 }, { stagger: 0.05 })}>
        Reveal items
      </button>
    </div>
  );
}

Motion Values & Transforms

import {
  useMotionValue, useTransform, useSpring,
  useVelocity, useTime,
} from '@dg-ui-react/react/motion';

const x = useMotionValue(0);
const rotate = useTransform(x, [-200, 200], [-15, 15]);
const opacity = useTransform(x, [-200, 0, 200], [0.5, 1, 0.5]);
const smoothX = useSpring(x, { stiffness: 300, damping: 30 });
const xVelocity = useVelocity(x);
const time = useTime(); // elapsed ms as MotionValue

Scroll-Linked Animation

import { useScrollTrigger, useScrollMotion, useInViewMotion } from '@dg-ui-react/react/motion';

// Scrub a timeline to scroll position
useScrollTrigger({
  trigger: '#section',
  start: 'top 80%',
  end: 'bottom 20%',
  scrub: true,
  onEnter: () => tl.play(),
  onLeaveBack: () => tl.reverse(),
});

// Parallax
function ParallaxHero() {
  const { scrollProgress } = useScrollMotion();
  const y = useTransform(scrollProgress, [0, 1], [0, -200]);
  return <motion.div style={{ y }}>Parallax content</motion.div>;
}

// Viewport detection
function FadeInSection() {
  const { ref, inView } = useInViewMotion({ once: true, margin: '-15%' });
  return (
    <motion.div ref={ref} animate={inView ? { opacity: 1 } : { opacity: 0 }}>
      Appears on scroll
    </motion.div>
  );
}

Gesture System

import { useGesture, useDrag, useDragControls } from '@dg-ui-react/react/motion';

// Preset gestures (button, card, listItem)
const gesture = useGesture('button');
<motion.button {...gesture}>Click me</motion.button>

// Full drag with bounds, snap, and momentum
const drag = useDrag({
  drag: 'x',
  dragConstraints: { left: -200, right: 200 },
  dragElastic: 0.2,
  dragMomentum: true,
  onDragEnd: (_, info) => {
    if (info.offset.x > 100) handleSwipeRight();
  },
});

// Long-press, double-tap, pinch, swipe
const swipe = useGesture({
  onSwipe: ({ direction }) => navigate(direction),
  onLongPress: () => openContextMenu(),
  onPinch: ({ scale }) => setZoom(scale),
});

Layout Animation

import { useLayoutAnimation, useSharedLayout, LayoutGroup } from '@dg-ui-react/react/motion';

// FLIP-based smooth layout transition
function ExpandableCard({ expanded }) {
  const layout = useLayoutAnimation();
  return (
    <motion.div {...layout} className={expanded ? 'h-64' : 'h-16'}>
      {expanded && <p>Details...</p>}
    </motion.div>
  );
}

// Shared element transitions across components
<LayoutGroup>
  <Tab layoutId="underline" /> {/* smoothly animates between tab positions */}
</LayoutGroup>

Text Animation

import { TextMotion, useTextSplit } from '@dg-ui-react/react/motion';

// 30+ built-in text effects
<TextMotion effect="typewriter" speed={0.04}>Hello World</TextMotion>
<TextMotion effect="scramble" duration={0.8}>Loading…</TextMotion>
<TextMotion effect="wave" stagger={0.03}>Wave text</TextMotion>

// Manual split + animate
const { chars, words } = useTextSplit('#heading');
animate(chars, { y: [20, 0], opacity: [0, 1] }, { stagger: 0.02 });

SVG Animation

import { useSVGMorph, usePathDraw, useFollowPath } from '@dg-ui-react/react/motion';

// Shape morphing
const morph = useSVGMorph({ from: '#shape-a', to: '#shape-b' });
morph.play();

// Path drawing (DrawSVG equivalent, free)
const draw = usePathDraw({ pathLength: 0 });
animate(draw.ref.current, { pathLength: 1 }, { duration: 1.5, ease: 'easeInOut' });

// Follow a path with auto-rotate
useFollowPath({ path: '#track', target: '#car', rotate: true });

Physics Engine

import { useGravity, useMagnetic, useParticleEmitter } from '@dg-ui-react/react/motion';

// Gravity with floor bounce
useGravity({ targets: '.ball', floor: 400, bounce: 0.7 });

// Magnetic attraction on hover
useMagnetic({ target: '#btn', strength: 0.4, falloff: 'quadratic' });

// Particle presets: confetti, snow, sparks, smoke, rain, fireflies
const emitter = useParticleEmitter({
  preset: 'confetti',
  count: 200,
  origin: { x: 0.5, y: 0 },
});
emitter.fire();

Tailwind CSS Plugin

DG Motion ships a first-party Tailwind plugin that replaces tailwindcss-animate and tailwindcss-motion with a superset of their combined features:

// tailwind.config.js
import { dgMotionPlugin } from '@dg-ui-react/react/motion';

export default {
  plugins: [dgMotionPlugin()],
};
<!-- 100% tailwindcss-animate compat -->
<div class="animate-in fade-in slide-in-from-top duration-300">...</div>

<!-- 100% tailwindcss-motion (Rombo) compat -->
<div class="motion-preset-fade motion-duration-300">...</div>

<!-- DG-exclusive: stagger children with CSS only -->
<ul class="motion-stagger-50">
  <li class="motion-preset-slide-up">Item 1</li>
  <li class="motion-preset-slide-up">Item 2</li>
</ul>

<!-- Scroll-triggered (CSS-only, no JS) -->
<div class="motion-on-scroll motion-preset-fade">Appears on scroll</div>

<!-- Reduced-motion safe -->
<div class="motion-reduced-safe motion-preset-bounce">...</div>

Performance Budgets & DevTools

import { MotionProvider, DevTools } from '@dg-ui-react/react/motion';

// Three performance tiers
<MotionProvider config={{ budget: 'full' }}>        {/* Default */}
<MotionProvider config={{ budget: 'performance' }}> {/* Reduces complex physics */}
<MotionProvider config={{ budget: 'minimal' }}>     {/* CSS fallbacks only */}

// In-app FPS monitor + timeline scrubber
<DevTools /> {/* add anywhere in the tree */}

18 Motion Presets

| Preset | Effect | | -------------- | -------------------------------------------------------- | | fadeIn | Opacity 0 → 1 | | fadeInUp | Fade + translate up | | fadeInDown | Fade + translate down | | fadeInLeft | Fade + translate from left | | fadeInRight | Fade + translate from right | | scaleIn | Fade + scale from 0.95 | | scaleInUp | Fade + scale + translate up | | popIn | Fade + scale from 0.9 (more pronounced) | | slideInLeft | Slide from -100% X | | slideInRight | Slide from +100% X | | slideInUp | Slide from +100% Y | | slideInDown | Slide from -100% Y | | expand | Height 0 → auto + fade | | collapse | Height auto → 0 + fade | | reveal | Fade + subtle scale + translate | | dismiss | Exit: fade + slide right + scale down | | highlight | Attention pulse (scale 1 → 1.03 → 1) | | none | Identity preset — no animation, for conditional toggling |

Design Tokens

Durations:

| Token | Seconds | Use Case | | ---------- | ------- | ----------------------------------- | | instant | 0 | Reduced-motion fallback | | fast | 0.12 | Menus, dropdowns, tooltips | | normal | 0.2 | Modals, backdrops, most transitions | | moderate | 0.3 | Accordions, reveals, expansions | | slow | 0.45 | Page-level animations | | slower | 0.6 | Dramatic emphasis, onboarding |

Springs:

| Preset | Stiffness | Damping | Use Case | | --------- | --------- | ------- | --------------------- | | default | 400 | 30 | Dialogs, toasts | | snappy | 500 | 35 | Dropdowns, toggles | | gentle | 300 | 28 | Drawers, sheets | | bouncy | 600 | 18 | Notifications, badges | | stiff | 700 | 40 | Button feedback |

Easings: linear, easeOut, easeIn, easeInOut, emphasized, decelerate, accelerate, plus 80+ named eases (power1.in, elastic.out, bounce.inOut, etc.)

Theme-Aware Motion

Each theme has its own motion personality — speed multiplier, spring stiffness, easing preferences.

<MotionProvider config={{ theme: 'obsidian' }}>
  <App /> {/* Crisp, professional springs */}
</MotionProvider>

<MotionProvider config={{ theme: 'vapor' }}>
  <App /> {/* Dreamy, floaty motion with gentler springs */}
</MotionProvider>

| Theme | Character | Preference | | ----------- | --------------------------------- | ------------------------------------------ | | Obsidian | Crisp, professional | Spring-based (stiffness: 450, damping: 32) | | Aurora | Soft, elegant, slightly slower | Easing-based (speed: 1.1×) | | Forge | Punchy, direct, faster | Spring-based (speed: 0.9×) | | Mobile | Fast, responsive, momentum-driven | Spring-based (speed: 0.85×) | | Neon | Energetic, bouncy | Spring-based (stiffness: 500, damping: 22) | | Vapor | Dreamy, floaty, slow | Spring-based (speed: 1.15×) | | Retro | Warm, weighted | Spring-based (stiffness: 320, damping: 28) | | Glass | Smooth, glassy | Easing-based (speed: 1.05×) | | Scholar | Restrained, minimal | Easing-based (speed: 1.2×) | | Corporate | Professional, no-nonsense | Easing-based (speed: 0.95×) | | Memphis | Playful, bouncy | Spring-based (stiffness: 550, damping: 20) | | Bio-Organic | Organic, flowing | Spring-based (stiffness: 280, damping: 24) |

Accessibility

Every motion hook and component automatically respects prefers-reduced-motion. Three enforcement tiers:

  • zero-duration — all durations collapse to 0ms (default reduced-motion behavior)
  • smart reduction — preserves informative transitions, removes decorative ones
  • epilepsy safety — automatically caps animations that flash faster than 3Hz

Override globally:

<MotionProvider config={{ reducedMotion: true }}>
  {/* All animations reduced regardless of OS setting */}
</MotionProvider>

Migration from framer-motion

If you were previously using framer-motion directly, DG Motion provides a fromMotion() config translator and a codemod CLI:

npx dg-motion migrate --from framer-motion

Or translate config objects at runtime:

import { fromMotion } from '@dg-ui-react/react/motion';

const dgConfig = fromMotion({
  initial: { opacity: 0 },
  animate: { opacity: 1 },
  transition: { duration: 0.3 },
});

TypeScript

All components ship with full TypeScript declarations. Import types alongside components:

import { Button } from '@dg-ui-react/react/obsidian';
import type { ButtonProps, ButtonVariant, ButtonSize } from '@dg-ui-react/react/obsidian';

import type { PricingTier } from '@dg-ui-react/react/aurora';
import type { RetroComponentProps, RetroPalette } from '@dg-ui-react/react/retro';
import type { MotionPresetName, ThemeName, EaseName } from '@dg-ui-react/react/motion';

TypeScript Configuration

Set moduleResolution to a strategy that supports package.json exports:

{
  "compilerOptions": {
    "moduleResolution": "bundler"
  }
}

Compatible values: "bundler", "node16", "nodenext".


Framework Integration

Vite + React

// src/main.tsx
import '@dg-ui-react/react/styles.css';

Next.js App Router

// app/layout.tsx
import '@dg-ui-react/react/styles.css';

DG Motion animations run client-side. Add 'use client' at the top of files that import animated DG-UI components. For zero-flash SSR, DG Motion pre-renders initial animation states as inline CSS @keyframes — no layout shift.

Next.js Pages Router

// pages/_app.tsx
import '@dg-ui-react/react/styles.css';

Remix

// app/root.tsx
import dgStyles from '@dg-ui-react/react/styles.css?url';
export const links = () => [{ rel: 'stylesheet', href: dgStyles }];

Complete Example

import '@dg-ui-react/react/styles.css';

import { Button, Card, Input, Tabs } from '@dg-ui-react/react/obsidian';
import { PricingCard } from '@dg-ui-react/react/aurora';
import { Badge } from '@dg-ui-react/react/neon';
import { Motion, MotionProvider, MotionPresence } from '@dg-ui-react/react/motion';
import { useState } from 'react';

import type { TabItem } from '@dg-ui-react/react/obsidian';

const tabs: TabItem[] = [
  { value: 'overview', label: 'Overview' },
  { value: 'pricing', label: 'Pricing' },
];

export default function App() {
  const [activeTab, setActiveTab] = useState('overview');
  const [showDialog, setShowDialog] = useState(false);

  return (
    <MotionProvider config={{ theme: 'obsidian' }}>
      <Motion preset="fadeInUp">
        <Card>
          <Badge variant="success">Live</Badge>
          <Tabs items={tabs} value={activeTab} onValueChange={setActiveTab} />

          <MotionPresence>
            {activeTab === 'overview' && (
              <Motion preset="fadeIn">
                <Input placeholder="Search components..." />
                <Button variant="primary" onClick={() => setShowDialog(true)}>
                  Open Dialog
                </Button>
              </Motion>
            )}
          </MotionPresence>
        </Card>
      </Motion>
    </MotionProvider>
  );
}

Troubleshooting

Components render with no styles — The stylesheet import is missing or placed too late. Put import '@dg-ui-react/react/styles.css' at the top of your application root, before any other CSS imports.

Animations are missing — Ensure you are not importing from an outdated cached version that listed framer-motion as a peer dep. Run npm install @dg-ui-react/react@latest — DG Motion is fully bundled, no extra install needed.

Next.js App Router: "You're importing a component that needs useState" — Add 'use client' at the top of the file where you import DG-UI components.

TypeScript cannot find module '@dg-ui-react/react/obsidian' — Set moduleResolution to "bundler", "node16", or "nodenext" in tsconfig.json.

Bundle size seems large — Use subpath imports (@dg-ui-react/react/obsidian) instead of root imports. Per-theme entry points give bundlers the narrowest possible tree-shaking surface. The motion engine is split into its own entry point (@dg-ui-react/react/motion) and is not included in theme bundles unless imported.


What's Included

| Feature | Details | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Themes | 15 published design themes, each with its own subpath entry point | | Components | 1,478+ exports across all themes | | Motion Engine | Zero-dependency DG Motion: 80+ eases, spring physics, timelines, scroll, gestures, drag, layout FLIP, text animation, SVG morph, particles, Tailwind plugin | | TypeScript | Full declarations for every component, hook, and type | | CSS | Single pre-compiled stylesheet — no Tailwind config needed in consumer projects | | Tree-Shaking | ESM + CJS dual output via tsup, per-theme entry points | | Accessibility | Three-level reduced-motion enforcement in every animated component | | Framework Support | Vite, Next.js (App Router + Pages Router), Remix | | Zero Dependencies | No framer-motion, no GSAP, no tailwindcss-animate — all motion is bundled |


About

@dg-ui-react/react is created and maintained by AahPlexX.

License

MIT — Copyright © 2026 AahPlexX