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

nutriguard-ui

v1.0.1

Published

NutriGuard Design System - Black/White/Red Minimalism Component Library based on Google Stitch architecture

Readme

nutriguard-ui


🎨 Philosophy

NutriGuard is a design system that combines:

  • Google Stitch (Material You 3) dynamic architecture
  • Black/White/Red strict minimalism
  • Motion as information flow, not decoration

Core Principles

  1. Strict Color Palette: Only Black (#000), White (#FFF), Red (#DC2626), and limited Gray scale
  2. 4px Grid System: All spacing must be multiples of 4px
  3. Hard Shadows Only: No soft blur shadows
  4. Minimal Border Radius: 0px or 8px maximum
  5. No Emoji Policy: SVG icons only (Lucide React)
  6. Bold Borders: 2px standard, no 1px lines
  7. Framer Motion: All animations use spring physics

📦 Installation

npm install nutriguard-ui framer-motion lucide-react

Peer Dependencies

{
  "react": "^18.0.0",
  "react-dom": "^18.0.0"
}

Tailwind CSS Setup

Add to your tailwind.config.js:

module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}",
    "./node_modules/nutriguard-ui/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      colors: {
        black: '#000000',
        white: '#FFFFFF',
        red: '#DC2626',
      },
      boxShadow: {
        'hard': '4px 4px 0 0 #000',
        'hard-lg': '8px 8px 0 0 #000',
      },
    },
  },
}

🚀 Quick Start

Basic Usage

import { Button, Card, Modal, ToastProvider, useToast } from 'nutriguard-ui';

function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <ToastProvider>
      <Card padding="md" hoverable>
        <h1>Welcome to NutriGuard</h1>
        <Button 
          variant="primary" 
          onClick={() => setIsModalOpen(true)}
        >
          Open Modal
        </Button>
      </Card>

      <Modal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        title="Example Modal"
      >
        <p>This is a modal with backdrop blur and hard shadow.</p>
      </Modal>
    </ToastProvider>
  );
}

Toast Notifications

import { useToast } from 'nutriguard-ui';

function MyComponent() {
  const { success, error, warning, info } = useToast();

  return (
    <Button onClick={() => success('Operation completed!')}>
      Show Success
    </Button>
  );
}

🧩 Components

Button

Interactive button with motion and multiple variants.

<Button variant="primary" size="md" loading={false}>
  Click Me
</Button>

Props:

  • variant: 'default' | 'primary' | 'red' | 'outline' | 'ghost'
  • size: 'sm' | 'md' | 'lg'
  • loading: boolean
  • iconLeft, iconRight: React.ReactNode

Card

Container with border and hover shadow effect.

<Card hoverable largeShadow padding="md">
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
  </CardHeader>
  <CardContent>
    Content goes here
  </CardContent>
  <CardFooter>
    <Button>Action</Button>
  </CardFooter>
</Card>

Modal

Full-screen overlay with centered content.

<Modal
  isOpen={isOpen}
  onClose={onClose}
  title="Modal Title"
  size="md"
  closeOnBackdrop={true}
>
  <p>Modal content</p>
  <ModalFooter>
    <Button onClick={onClose}>Close</Button>
  </ModalFooter>
</Modal>

Toast

Auto-dismiss notification system.

// Wrap your app with ToastProvider
<ToastProvider maxToasts={5}>
  <App />
</ToastProvider>

// Use in components
const { success, error, warning, info } = useToast();
success('Success message', 'Optional Title', 5000);

Drawer

Slide-in panel from screen edges.

<Drawer
  isOpen={isOpen}
  onClose={onClose}
  position="right"
  size="md"
  title="Drawer Title"
>
  <p>Drawer content</p>
  <DrawerFooter>
    <Button onClick={onClose}>Close</Button>
  </DrawerFooter>
</Drawer>

Dialog

Simple confirmation dialog.

<Dialog
  isOpen={isOpen}
  onClose={onClose}
  title="Confirm Action"
  description="Are you sure you want to proceed?"
  confirmText="Yes, proceed"
  cancelText="Cancel"
  onConfirm={handleConfirm}
  variant="danger"
  showIcon
/>

Input & Textarea

Text input with validation states.

<Input
  label="Email"
  type="email"
  placeholder="Enter your email"
  state="default"
  helperText="We'll never share your email"
  iconLeft={<Mail />}
/>

<Textarea
  label="Message"
  placeholder="Enter your message"
  rows={4}
  helperText="Max 500 characters"
/>

Spinner & Badge

<Spinner size="md" />

<Badge variant="primary" size="sm">NEW</Badge>
<Badge variant="red">Alert</Badge>

🎬 Animations

Using Variants

import { buttonVariants, cardVariants } from 'nutriguard-ui';
import { motion } from 'framer-motion';

<motion.div variants={cardVariants} initial="initial" whileHover="hover">
  Animated Card
</motion.div>

Available Variants

  • buttonVariants - Scale on hover/tap
  • cardVariants - Shadow lift on hover
  • modalVariants - Center entrance
  • drawerVariants - Slide from edges
  • toastVariants - Slide from top-right
  • dialogVariants - Drop from top
  • staggerContainerVariants - Stagger children
  • collapseVariants - Accordion animation

🎨 Design Tokens

Colors

import { colors } from 'nutriguard-ui';

colors.black    // #000000
colors.white    // #FFFFFF
colors.red      // #DC2626
colors.gray[400] // #9CA3AF

Spacing (4px Grid)

import { spacing } from 'nutriguard-ui';

spacing[1]  // 4px
spacing[2]  // 8px
spacing[4]  // 16px
spacing[6]  // 24px
spacing[12] // 48px

Typography

import { typography } from 'nutriguard-ui';

typography.fontFamily.sans  // 'Inter'
typography.fontSize.base    // '16px'
typography.fontWeight.bold  // 700

🚫 Anti-Patterns

❌ DON'T

// ❌ Using emoji
<Button>Save 💾</Button>

// ❌ Soft shadows
<div style={{ boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }} />

// ❌ Non-grid spacing
<div style={{ padding: '13px' }} />

// ❌ Unauthorized colors
<Button style={{ background: '#3B82F6' }} />

// ❌ Large border radius
<Card style={{ borderRadius: '20px' }} />

✅ DO

// ✅ Use SVG icons
<Button iconLeft={<Save />}>Save</Button>

// ✅ Hard shadows
<Card hoverable largeShadow />

// ✅ 4px grid spacing
<div className="p-4" /> // 16px

// ✅ Strict palette
<Button variant="primary" />

// ✅ Minimal radius
<Card /> // 8px default

📚 Examples

Full Page Example

import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  Modal,
  ToastProvider,
  useToast,
} from 'nutriguard-ui';
import { ArrowRight } from 'lucide-react';

function Dashboard() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { success } = useToast();

  const handleSave = () => {
    success('Changes saved successfully!');
    setIsModalOpen(false);
  };

  return (
    <div className="max-w-[1440px] mx-auto px-8 py-16">
      <div className="grid grid-cols-3 gap-6">
        <Card hoverable>
          <CardHeader>
            <CardTitle>Analytics</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-4xl font-black">1,234</p>
            <p className="text-sm text-gray-600">Total Users</p>
          </CardContent>
        </Card>

        <Card hoverable onClick={() => setIsModalOpen(true)}>
          <CardHeader>
            <CardTitle>Settings</CardTitle>
          </CardHeader>
          <CardContent>
            <p>Click to configure</p>
          </CardContent>
        </Card>
      </div>

      <Modal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        title="Settings"
        size="md"
      >
        <p>Configure your settings here.</p>
        <div className="flex gap-4 mt-6">
          <Button variant="outline" fullWidth onClick={() => setIsModalOpen(false)}>
            Cancel
          </Button>
          <Button variant="primary" fullWidth onClick={handleSave} iconRight={<ArrowRight />}>
            Save Changes
          </Button>
        </div>
      </Modal>
    </div>
  );
}

function App() {
  return (
    <ToastProvider>
      <Dashboard />
    </ToastProvider>
  );
}

🛠 Development

# Install dependencies
npm install

# Start dev server
npm run dev

# Build library
npm run build

# Run tests
npm test

# Start Storybook
npm run storybook

📄 License

MIT © Nutrivision


🙏 Credits

  • Google Material Design Team - Stitch architecture inspiration
  • Framer - Motion library
  • Lucide - Icon system
  • Tailwind CSS - Utility-first CSS

📞 Support