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

no-please

v1.0.0

Published

Reasons to say no, in five escalating levels of politeness. No instance required.

Downloads

12

Readme

no-please

Reasons to say no, in five escalating levels of politeness.

This package returns a string. That's it. That's the package.

It has no dependencies, because it would be genuinely difficult to need any. It has 380 lines of build tooling and type definitions wrapped around what is, functionally, an array of excuses. I'm aware. We're all aware.

Install

npm install no-please

Yes, you are adding a dependency for this. No, I won't stop you. Boundaries are the whole theme here and I'm not going to violate mine by lecturing you about yours.

Use it

import noPlease from 'no-please';

noPlease();          // 'Nah, I'm good.'
noPlease('polite');  // "I'd love to, but my calendar has other plans for me."
noPlease('extreme'); // 'That is a no so large it has its own weather system.'

No new. No NoPleaseFactory. No .init() you'll forget to call and then spend forty minutes debugging. You call the function, it says no. This is the one design decision in the entire project I'm proud of.

Levels

| Level | For | |---|---| | polite | People whose opinion of you matters | | casual | Default. How you actually talk | | rude | People who booked the meeting at 4:45pm on a Friday | | extreme | Recreational use only | | poet | You own a fountain pen and we both know it |

Anything else throws a TypeError that tells you the valid levels, which is more helpful error handling than the problem strictly warrants.

API

The API section. For an API with one function in it.

noPlease(level?)

Returns one excuse. level defaults to 'casual'.

noPlease('rude'); // 'Absolutely not. Next question.'

noPlease(options?)

For when a string is not enough ceremony.

noPlease({ level: 'poet' });
noPlease({ level: 'rude', random: () => 0 }); // deterministic, for tests

random exists purely so your snapshot tests don't flake. You're welcome. It's the only feature in here that came from an actual engineering concern.

noPlease.all(level?)

Every excuse at that level, as a fresh array. Mutate it all you want, it's a copy.

noPlease.levels

['polite', 'casual', 'rude', 'extreme', 'poet']. Build a dropdown out of your refusals. Live your truth.

Works in your framework

It's a synchronous function that returns a string and touches nothing. It works everywhere. But the internet demands a compatibility section, so:

React

import noPlease from 'no-please';

function DeclineButton() {
  const [excuse, setExcuse] = useState('');
  return (
    <>
      <button onClick={() => setExcuse(noPlease('polite'))}>Decline</button>
      <p>{excuse}</p>
    </>
  );
}

There is no useNoPlease() hook. A hook would mean a React peer dependency, a rules-of-hooks footgun, and one more thing to version. It's a function. Call it.

Next.js

Works in server components, client components, route handlers, and middleware. Ships both ESM and CJS builds and imports nothing, so there is no 'use client' boundary to negotiate.

export async function GET() {
  return Response.json({ reason: noPlease('rude') });
}

NestJS

import { Injectable } from '@nestjs/common';
import noPlease from 'no-please';

@Injectable()
export class ExcuseService {
  decline(): string {
    return noPlease('polite');
  }
}

Do not put this in a provider and inject it. I know you want to. Resist.

Express

const express = require('express');
const noPlease = require('no-please');

app.get('/no', (req, res) => res.send(noPlease(req.query.level)));

require() hands you the function directly, not { default: fn }. That took a build script to guarantee and I'd like exactly one person to notice.

TypeScript

Fully typed. The Level union is exported, so your editor will autocomplete five string literals at you.

import noPlease, { type Level } from 'no-please';

FAQ

Is this a joke? It's a functioning, tested, typed, dual-format npm package. Those two things aren't mutually exclusive, which is arguably the problem with this whole ecosystem.

Can you add more excuses? Sure. PRs welcome. Please put them in the right level; a polite excuse that lands in extreme will get someone fired and it won't be me.

Can you add i18n / an LLM / a plugin system?

noPlease('extreme');

Contributing

Fork it, add strings to src/reasons.ts, run npm test, open a PR. The test suite is more rigorous than the subject matter deserves and I'd appreciate it if you kept it green.

License

MIT. Say no freely, commercially, and without attribution.