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

giggle-guard

v1.1.2

Published

๐Ÿ›ก๏ธ Giggle Guard - A curated collection of 3000+ hilarious validation messages that turn boring form errors into delightful user experiences. Make your users smile instead of rage-quit!

Downloads

10

Readme

๐Ÿ›ก๏ธ Giggle Guard

3000+ hilarious validation messages that make your users smile instead of rage-quit when they mess up forms. Because who says error messages have to be boring?

๐ŸŽฏ Why Giggle Guard?

  • ๐Ÿšซ Users hate boring error messages โ†’ Make them laugh instead of cry ๐Ÿ˜ญ
  • ๐ŸŽญ Generic validation is forgettable โ†’ Stand out like a glitter bomb in a library
  • ๐Ÿ“‹ Copy-paste ready messages โ†’ Say goodbye to "Field is required." Forever. ๐Ÿ”ฅ
  • ๐Ÿ“ˆ Boost user engagement โ†’ Happy users fill forms. Sad users click away.
  • ๐ŸŒŸ Open source humor โ†’ Fueled by developer memes and community chuckles

๐Ÿ“ฆ Installation

npm install giggle-guard
yarn add giggle-guard
pnpm add giggle-guard

๐Ÿš€ Quick Start

One-liner Usage

import { getMessage } from "giggle-guard";

const message = getMessage({
  fieldType: "email",
  errorType: "required",
});
console.log(message); // "Even my spam folder has higher standards"

Instance Usage

import { GiggleGuard } from "giggle-guard";

const guard = new GiggleGuard({
  defaultTone: "sarcastic",
  trackUsedMessages: true,
});

const funnyMessage = guard.getMessage({
  fieldType: "password",
  errorType: "tooWeak",
  tone: "funny",
});

Multiple Messages

import { getMessages } from "giggle-guard";

const messages = getMessages(
  {
    fieldType: "email",
    errorType: "invalid",
  },
  3
);

๐ŸŽญ Available Tones

| Tone | Vibe | Perfect For | Sample Message | | ----------------- | ----------------------- | --------------------- | --------------------------------------------------------------------------------- | | casual ๐Ÿ˜Ž | Laid-back buddy | Relaxed apps | "Hey, looks like you forgot something here" | | dark ๐Ÿ–ค | Edgy humor | Millennial apps | "This field is as empty as my soul" | | dramatic ๐ŸŽญ | Shakespeare meets forms | Creative platforms | "BEHOLD! A field left barren and forgotten!" | | friendly ๐Ÿ˜Š | Your helpful neighbor | Family apps | "Oops! This little field needs some love" | | funny ๐Ÿ˜‚ | Classic comedy | Universal appeal | "This field is lonelier than a pizza slice at a salad convention" | | genZ ๐Ÿ’… | Internet culture | Social media apps | "This field said 'no cap' to being filled out bestie" | | millennial ๐Ÿฅ‘ | Nostalgic references | 25-40 demographic | "This field is more empty than my bank account after avocado toast" | | motivational ๐Ÿ’ช | Encouraging coach | Fitness/productivity | "You're almost there! Just fill this field and conquer the world!" | | mysterious ๐Ÿ”ฎ | Cryptic wisdom | Gaming/fantasy | "The ancient prophecy requires... your email address" | | nerdy ๐Ÿค“ | Tech humor | Developer tools | "ERROR 404: Field content not found. Have you tried turning it off and on again?" | | poetic ๐ŸŒน | Artistic flair | Creative platforms | "Like a canvas awaits paint, this field awaits your touch" | | popCulture ๐ŸŽฌ | Movie/TV references | Entertainment apps | "Use the force, Luke... to fill out this field" | | professional ๐Ÿ‘” | Business appropriate | Corporate apps | "This field requires your attention to proceed successfully" | | sarcastic ๐Ÿ™„ | Witty sass | Apps with personality | "Oh wonderful, another empty field. Just what we needed." | | witty ๐Ÿง  | Clever wordplay | Smart audiences | "This field is having an identity crisis - it doesn't know what it wants to be" |

๐Ÿ“‹ Supported Field Types

| Field Type | Description | Common Use Cases | Hilarious Error Example | | --------------- | ----------------------- | --------------------- | ------------------------------------------------------------------- | | address ๐Ÿ  | Street addresses | Shipping, billing | "GPS can't find you if you don't tell us where you live!" | | checkbox โ˜‘๏ธ | Checkbox selections | Terms, preferences | "Even robots need to agree to terms and conditions" | | creditCard ๐Ÿ’ณ | Credit card numbers | Payments | "Your credit card number looks faker than a $3 bill" | | date ๐Ÿ“… | Date inputs | Birth dates, events | "Time travel isn't invented yet, pick a real date" | | email ๐Ÿ“ง | Email addresses | Registration, contact | "Even my spam folder has higher standards than this" | | file ๐Ÿ“ | File uploads | Documents, images | "Upload failed harder than my last relationship" | | general ๐Ÿ“ | Generic form fields | Miscellaneous | "This field is more confused than a chameleon in a bag of Skittles" | | name ๐Ÿ‘ค | Name inputs | User identification | "Anonymous is taken, try something else" | | password ๐Ÿ”’ | Password fields | Security | "This password is weaker than gas station sushi" | | phone ๐Ÿ“ฑ | Phone numbers | Contact info | "Is this a phone number or a random number generator result?" | | radio ๐Ÿ”˜ | Radio button selections | Single choice options | "Pick one! This isn't a buffet!" | | select ๐Ÿ“‹ | Dropdown selections | Categories, options | "Choose your fighter... I mean, option" | | time โฐ | Time inputs | Scheduling | "Time's not real, but this field still needs filling" | | url ๐ŸŒ | Website URLs | Links, references | "This URL is more broken than my New Year's resolutions" | | zipcode ๐Ÿ“ฎ | Postal codes | Location data | "This ZIP code doesn't exist, unlike my crippling anxiety" |

โŒ Error Types

| Error Type | When It Happens | Field Examples | Comedy Gold Example | | ---------------- | --------------------- | --------------------- | -------------------------------------------------------------------- | | doesntMatch โŒ | Values don't match | Password confirmation | "These passwords match like pineapple matches pizza (controversial)" | | duplicate ๐Ÿ”„ | Value already exists | Username, email | "Sorry, that username is taken by someone cooler than you" | | expired โฐ | Value has expired | Credit cards, tokens | "This expired faster than milk in the sun" | | exists ๐Ÿ“ | Item already exists | Account creation | "Plot twist: You already exist in our system!" | | format ๐ŸŽญ | Incorrect format | Dates, numbers | "Format error: Expected awesome, got whatever this is" | | inFuture ๐Ÿš€ | Date is in future | Birth dates | "Unless you're a time traveler, pick a date that's already happened" | | inPast ๐Ÿฆ• | Date is in past | Event dates | "That date is more ancient than dial-up internet" | | invalid ๐Ÿšซ | General invalid value | Any field | "This value is as invalid as my life choices" | | invalidCVV ๐Ÿ’ณ | Bad credit card CVV | Payment forms | "CVV stands for 'Can't Validate Visually' apparently" | | invalidType ๐Ÿ“Ž | Wrong file/data type | File uploads | "Expected a JPEG, got disappointment instead" | | notSelected ๐Ÿ‘† | No selection made | Dropdowns, radios | "Commitment issues? Pick something already!" | | outOfRange ๐Ÿ“Š | Value outside limits | Age, quantity | "That number is more out of range than my WiFi signal" | | required โš ๏ธ | Field is required | Essential fields | "This field isn't optional, unlike my social life" | | tooLarge ๐Ÿ“ | File/value too big | File uploads | "That file is larger than my student debt" | | tooLong ๐Ÿ“ | String too long | Text inputs | "Shorter than a CVS receipt, please" | | tooShort โœ‚๏ธ | String too short | Passwords, names | "Shorter than my patience with slow WiFi" | | tooSmall ๐Ÿ” | Value too small | Numbers | "Smaller than my motivation on Monday mornings" | | tooWeak ๐Ÿ’ช | Password not strong | Password fields | "This password is weaker than my willpower at a donut shop" |

๐ŸŽช Hilarious Message Samples by Tone

๐Ÿ˜‚ Funny Tone - Classic Comedy Gold

| Field + Error | Message | Why It's Hilarious | | ----------------------- | ----------------------------------------------------- | ----------------------------------- | | email + required | "Even my spam folder has higher standards" | Roasts the user AND email marketing | | password + tooShort | "This password is shorter than a TikTok video" | Relatable modern reference | | name + required | "Anonymous is so last year, what's your actual name?" | Playful peer pressure | | phone + invalid | "Is this a phone number or your WiFi password?" | Confusion comedy | | file + tooLarge | "This file is bigger than my hopes and dreams" | Self-deprecating humor |

๐Ÿ™„ Sarcastic Tone - Passive Aggressive Perfection

| Field + Error | Message | Sass Level | | ------------------------ | ------------------------------------------------------ | ---------- | | address + required | "Oh sure, we'll just mail it to 'somewhere on Earth'" | ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ | | url + invalid | "Congratulations! You've broken the internet" | ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ | | password + tooWeak | "That's cute. My grandma's password is stronger" | ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ | | date + inFuture | "Time travel much? Pick a date that actually happened" | ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ | | creditCard + invalid | "This credit card number is faker than reality TV" | ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ |

๐Ÿ’… GenZ Tone - Internet Culture Supreme

| Field + Error | Message | Meme Factor | | ----------------------- | ----------------------------------------------------------- | ------------------------- | | name + duplicate | "Sorry bestie, that username is already taken ๐Ÿ’…" | โœจMain Character Energyโœจ | | email + invalid | "This email address is giving 'fake account' vibes fr fr" | ๐Ÿ“ฑ No Cap ๐Ÿ“ฑ | | phone + required | "Drop that number bestie or you're getting ghosted ๐Ÿ‘ป" | ๐Ÿ’ฏ Slaps Different ๐Ÿ’ฏ | | password + tooShort | "This password ain't it chief, make it longer periodt" | ๐Ÿšซ๐Ÿงข Facts Only ๐Ÿšซ๐Ÿงข | | file + invalidType | "This file format is NOT giving what it's supposed to give" | ๐Ÿ’€ I'm Deceased ๐Ÿ’€ |

๐Ÿ–ค Dark Tone - Existential Dread Meets Forms

| Field + Error | Message | Darkness Level | | ---------------------- | ---------------------------------------------------------------------- | -------------- | | email + required | "This field is as empty as my soul on Monday mornings" | ๐ŸŒš๐ŸŒš๐ŸŒš | | password + tooWeak | "This password offers less protection than my emotional walls" | ๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš | | name + required | "Identity crisis? Join the club. But first, enter your name" | ๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš | | phone + invalid | "This number is more disconnected than my relationship with happiness" | ๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš๐ŸŒš | | date + required | "Time is a construct, but this field still needs a date" | ๐ŸŒš๐ŸŒš๐ŸŒš |

๐Ÿค“ Nerdy Tone - 404: Humor Not Found

| Field + Error | Message | Geek Level | | ----------------------- | -------------------------------------------------------------------------------- | ---------- | | email + invalid | "REGEX ERROR: This email string failed to compile in reality.exe" | ๐Ÿค–โšก | | password + tooShort | "Insufficient entropy detected. Recommend adding 2 dragons and a prime number" | ๐Ÿ‰๐Ÿ”ข | | file + invalidType | "Expected MIME type: application/awesome. Received: disappointment/json" | ๐Ÿ“๐Ÿ’พ | | url + invalid | "HTTP 404: Valid URL Not Found. Have you tried turning the internet off and on?" | ๐ŸŒโšก | | phone + format | "Phone number pattern matching failed. Are you calling from another dimension?" | ๐Ÿ“ž๐ŸŒŒ |

๐ŸŽญ Dramatic Tone - Shakespeare Meets Silicon Valley

| Field + Error | Message | Drama Rating | | ---------------------- | ------------------------------------------------------------------------------------------- | ------------ | | name + required | "HARK! What light through yonder field breaks? 'Tis your name, and you forgot to enter it!" | ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ | | email + invalid | "Alas! This email address has fallen into the abyss of invalidity!" | ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ | | password + tooWeak | "Behold! A password so weak, it could not protect a sandcastle from the tide!" | ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ | | date + required | "Time stands still! The cosmic calendar awaits your input!" | ๐ŸŽญ๐ŸŽญ๐ŸŽญ | | file + tooLarge | "Lo! This file doth exceed the bounds of digital possibility!" | ๐ŸŽญ๐ŸŽญ๐ŸŽญ๐ŸŽญ |

๐Ÿฅ‘ Millennial Tone - Peak 2010s Nostalgia

| Field + Error | Message | Millennial Factor | | ----------------------- | ---------------------------------------------------------------------------- | ----------------- | | email + required | "This field is emptier than my bank account after buying avocado toast" | ๐Ÿฅ‘๐Ÿ’ธ | | password + tooShort | "This password is shorter than my attention span during Zoom meetings" | ๐Ÿ’ป๐Ÿ˜ด | | name + duplicate | "That username is more taken than the good parking spots at Target" | ๐ŸŽฏ๐Ÿš— | | phone + invalid | "This phone number is more disconnected than my landline from 2005" | ๐Ÿ“ž๐Ÿ“Ÿ | | date + inPast | "That date is older than my student loan debt (and that's saying something)" | ๐ŸŽ“๐Ÿ’ธ |

๐Ÿ’ช Motivational Tone - Tony Robbins Meets Tech Support

| Field + Error | Message | Motivation Level | | ---------------------- | -------------------------------------------------------------------- | ---------------- | | email + required | "You're AMAZING! Now show that amazingness by filling this field!" | ๐Ÿš€โญ | | password + tooWeak | "You're stronger than this password! Channel that inner strength!" | ๐Ÿ’ช๐Ÿ”ฅ | | name + required | "Your name has POWER! Share that power with this humble form field!" | โšก๐Ÿ‘‘ | | phone + invalid | "You're just ONE digit away from greatness! You've got this!" | ๐Ÿ“ฑโœจ | | file + invalidType | "Wrong format? No problem! Champions adapt and overcome!" | ๐Ÿ†๐Ÿ’ฏ |

๐Ÿ› ๏ธ All Available Methods

Core Methods

import { getMessage, getMessages, GiggleGuard } from "giggle-guard";

// Get a single message
const message = getMessage({
  fieldType: "email",
  errorType: "required",
  tone: "funny", // optional
  excludeUsed: true, // optional
});

// Get multiple messages
const messages = getMessages(
  {
    fieldType: "password",
    errorType: "tooWeak",
  },
  3
);

// Using the class instance
const guard = new GiggleGuard();

Instance Methods

const guard = new GiggleGuard();

// Core methods
guard.getMessage(options)
guard.getMessages(options, count)

// Lookup methods
guard.getMessageById(id)
guard.getMessagesByField(fieldType)
guard.getMessagesByTone(tone)

// Utility methods
guard.resetUsedMessages()
guard.getStats()
guard.updateConfig({ ... })

Validation Helper

import { validateFieldErrorCombo } from "giggle-guard";

const { valid, allowedErrors } = validateFieldErrorCombo("email", "required");
console.log(valid); // true
console.log(allowedErrors); // ["required", "invalid", "tooShort", ...]

โš™๏ธ Configuration Options

Giggle Guard comes with sensible defaults out of the box. Here's the configuration it uses internally unless you override it:

{
  defaultTone: "random",       // Use a random tone unless specified
  trackUsedMessages: true,     // Avoid repeating the same message
  fallbackToGeneric: true,     // Fallback to generic messages if none match
  strictValidation: false      // Log a warning instead of throwing an error
}

| Option | Type | Default | Description | | ------------------- | --------- | -------- | -------------------------------------------------------------------------- | | defaultTone | Tone | random | Sets the vibe for your messages. Want chaos? Set it to "random"!๐ŸŽฒ | | trackUsedMessages | boolean | true | Stops repeats like your friend who tells the same joke 5 times. ๐Ÿค | | fallbackToGeneric | boolean | true | If nothing fits, it'll pull out a trusty backup message from the vault. ๐Ÿ—ƒ๏ธ | | strictValidation | boolean | false | Turn this on to yell at bad input like a grumpy librarian. ๐Ÿ“š๐Ÿšซ |

โš›๏ธ Framework Integration Examples

React Hook Form

import { useForm } from "react-hook-form";
import { getMessage } from "giggle-guard";

function MyForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const getErrorMessage = (fieldType: string, errorType: string) => {
    return getMessage({ fieldType, errorType, tone: "millennial" });
  };

  return (
    <form onSubmit={handleSubmit(() => {})}>
      <input {...register("email", { required: true })} type="email" />
      {errors.email && <p>{getErrorMessage("email", "required")}</p>}
    </form>
  );
}

Formik

import { Formik, Form, Field, ErrorMessage } from "formik";
import { getMessage } from "giggle-guard";

<Formik
  initialValues={{ email: "" }}
  validate={(values) => {
    const errors: any = {};
    if (!values.email) {
      errors.email = getMessage({ fieldType: "email", errorType: "required" });
    }
    return errors;
  }}
  onSubmit={() => {}}
>
  <Form>
    <Field name="email" type="email" />
    <ErrorMessage name="email" component="div" />
  </Form>
</Formik>;

Vue + Vuelidate

<script setup>
import { ref } from "vue";
import { useVuelidate } from "@vuelidate/core";
import { required, email } from "@vuelidate/validators";
import { getMessage } from "giggle-guard";

const form = ref({ email: "" });
const rules = { email: { required, email } };
const $v = useVuelidate(rules, form);

const getEmailError = () => {
  if (!$v.value.email.required)
    return getMessage({ fieldType: "email", errorType: "required" });
  if (!$v.value.email.email)
    return getMessage({ fieldType: "email", errorType: "invalid" });
};
</script>

Angular

import { FormBuilder, Validators } from '@angular/forms';
import { getMessage } from 'giggle-guard';

constructor(private fb: FormBuilder) {}

form = this.fb.group({
  email: ['', [Validators.required, Validators.email]]
});

getEmailError() {
  const control = this.form.get('email');
  if (control?.hasError('required')) return getMessage({ fieldType: 'email', errorType: 'required' });
  if (control?.hasError('email')) return getMessage({ fieldType: 'email', errorType: 'invalid' });
  return '';
}

๐Ÿ”Œ Integrations & Plugins

Validation Libraries

// Yup
import * as yup from "yup";
import { getMessage } from "giggle-guard";

const schema = yup.object({
  email: yup
    .string()
    .required(() => getMessage({ fieldType: "email", errorType: "required" }))
    .email(() => getMessage({ fieldType: "email", errorType: "invalid" })),
});

// Zod
import { z } from "zod";
import { getMessage } from "giggle-guard";

const schema = z.object({
  email: z
    .string({
      required_error: getMessage({ fieldType: "email", errorType: "required" }),
    })
    .email(getMessage({ fieldType: "email", errorType: "invalid" })),
});

// Joi
import Joi from "joi";
import { getMessage } from "giggle-guard";

const schema = Joi.object({
  email: Joi.string()
    .required()
    .messages({
      "any.required": getMessage({ fieldType: "email", errorType: "required" }),
      "string.email": getMessage({ fieldType: "email", errorType: "invalid" }),
    }),
});

๐Ÿ“Š Statistics & Analytics

const guard = new GiggleGuard();
const stats = guard.getStats();

console.log(stats);
// {
//   total: 3000,
//   byFieldType: {
//     email: 150,
//     password: 200,
//     name: 100,
//     ...
//   },
//   byTone: {
//     funny: 400,
//     sarcastic: 350,
//     professional: 300,
//     ...
//   },
//   byErrorType: {
//     required: 500,
//     invalid: 400,
//     tooShort: 300,
//     ...
//   }
// }

โ“ FAQ

Q: Will these messages offend my users?
A: All messages are carefully curated to be playful, not offensive.

Q: Can I use this in a professional/corporate environment?
A: Absolutely! Use the professional tone for safer but still friendly humor.

Q: Can I contribute my own funny messages?
A: Yes! Fork the repo and submit a pull request.

Q: Does this work with server-side validation?
A: Yes! Works with browser, Node.js, and even edge functions.

Q: Will the same messages keep repeating?
A: Nope. trackUsedMessages prevents repetition unless you reset.

Q: Can I get message usage stats?
A: Yup! Use getStats() for field/tone/error type analytics.

Q: Can I change tones dynamically?
A: Yes! You can override the tone per message call.

Q: Is it production-ready?
A: Yes! Used in live apps, tested with 3000+ messages.

๐Ÿค Contributing

  • Add messages under /src/messages/[fieldType].ts
  • Write new tests under /tests
  • Keep humor universal, light, and accessible
  • Avoid slang that won't age well

๐Ÿ“ License

MIT โ€“ Use it anywhere, laugh everywhere.

โญ Star us on GitHub

If Giggle Guard made you (or your users) smile, give us a โญ and spread the laughs!


Made with โค๏ธ by Pratik Shikhaliya โ€” who's tired of boring error messages.

Remember: Life's too short for "This field is required"