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

sexy-af

v0.1.1

Published

A realistic makeup drawing toolkit with kajal, contour, lipstick, balm, highlighter, and mascara for React and the web.

Readme

sexy-af

A little makeup, a blank canvas. A drawing toolkit with six photographic cosmetic tools, fixed product shades, distinct finishes, and an eraser.

Early preview, v0.1.1. A self-contained React component and vanilla JavaScript studio. The package includes its styles and product artwork.

Personal, noncommercial use only. Commercial use and modified versions require separate written permission. Normal integration using the documented API and routine build steps is allowed for personal, noncommercial projects. See LICENSE for the full proprietary terms.

Run the playground

npm install
npm run dev

Open http://localhost:4317. The main demo saves its drawing in your browser. React integration demo: http://localhost:4317/react-demo.html.

Install

To draw over other websites, use the local browser extension. The npm package below embeds a studio in your own app.

npm install sexy-af

For React, install React 18 or 19 in your application. Vanilla users import sexy-af/vanilla and do not need React.

To test a local build before publishing:

npm pack --pack-destination artifacts
npm install /absolute/path/to/sexy-af-0.1.1.tgz

React

'use client';
import { Makeup } from 'sexy-af';

export default function Playground() {
  return <Makeup initialTool="lipstick" />;
}

React 18 and 19 are supported by the peer range. Styles are bundled and isolated in a Shadow DOM, with no global CSS or font requests. No stylesheet import is needed. React is an optional peer dependency so vanilla consumers do not have to install it. The component mounts only in the browser and cleans up on unmount, including React Strict Mode.

import { useRef } from 'react';
import { Makeup, type MakeupHandle } from 'sexy-af';

function Editor() {
  const makeup = useRef<MakeupHandle>(null);
  return <>
    <button onClick={() => makeup.current?.undo()}>Undo</button>
    <Makeup ref={makeup} storageKey="my-makeup-draft"
      onChange={strokes => console.log(strokes)} />
  </>;
}

Plain JavaScript

import { createMakeupStudio } from 'sexy-af/vanilla';

const studio = createMakeupStudio(document.querySelector('#studio'), {
  initialTool: 'mascara',
});
// Later, when removing the component:
studio.destroy();

Options and API

| Option | Default | Purpose | | --- | --- | --- | | initialTool | kajal | kajal, contour, lipstick, balm, highlighter, mascara, or sponge (eraser) | | initialStrokes | [] | Restore a drawing; takes priority over a saved draft | | initialBackground | #ffffff | Initial canvas color | | storageKey | omitted | Opt in to browser draft storage; use distinct keys for separate studios | | showBranding | false | Use the spacious standalone layout (legacy option name) | | onChange | omitted | Receives a detached stroke snapshot after changes and initialization | | className, style | omitted | React host element styling |

Initial options are read when the component mounts. Use a new React key to reset them. onChange can update without remounting. For an embedded studio, set --makeup-canvas-height on the host to control the drawing area height.

Both the React ref and vanilla instance expose getStrokes(), setStrokes(strokes), selectTool(id), undo(), redo(), clear(), and toPng(): Promise<Blob | null>. The vanilla instance additionally exposes destroy(). setStrokes() validates and clones input, normalizes color/size/opacity to the fixed product presets, and resets undo history. PNG export includes the selected paper color and erasure at 1440 pixels wide, with height matching the current canvas aspect ratio. Drawing coordinates use the same board dimensions. Resizing preserves proportions and anchors existing strokes to the top left; reducing canvas height can crop lower marks until it is expanded again.

Interaction

  • Mouse, touch, and pen drawing; pen pressure affects kajal and mascara pigment coverage.
  • Six photographic cosmetic tools with fixed shades, tip sizes, and coverage. Layer strokes to build color.
  • Kajal sparkle, creamy contour, rosewood lipstick sheen, cool-mauve glossy balm, dewy highlighter, and separated mascara bristles.
  • Undo, redo, reversible clear, partial erasing, and programmatic PNG export with toPng().
  • 1–6 select products, E selects the eraser, Cmd/Ctrl+Z undo, Shift+Cmd/Ctrl+Z redo. Shortcuts apply while focus is inside the studio.
  • Optional local draft persistence, responsive layout, reduced-motion support, labeled controls, and keyboard focus states. Freehand drawing itself requires a pointer.

Build and verify

npm run check
npm run build
npm test
npm run typecheck
npm pack --pack-destination artifacts

The tarball contains ESM, CommonJS, and TypeScript definitions. The development playground, tests, and React demo bundle are excluded. The vanilla entry has no runtime dependencies.

Toolbar interaction was inspired by Drawesome. Product artwork was generated from official product references with matched studio lighting. Colors and material effects are visual approximations, not exact physical simulations. See ASSETS.md for sources and generation prompts.

Products

| Tool ID | Product | Shade | | --- | --- | --- | | kajal | Victoria Beckham Beauty Satin Kajal Liner | Night Flash | | contour | Victoria Beckham Beauty Contour Stylus | Sandstone | | lipstick | Hermès Silky Lipstick Shine | 48 Rose Boisé | | balm | EADEM Le Chouchou | Fig Sauce | | highlighter | Chanel Baume Essentiel | Dragée | | mascara | Tom Ford Extreme Mascara | Raven |

The read-only PRODUCTS array is exported from both package entry points. Generated imagery and source links describe an independent prototype; brand affiliation is not implied.

Publishing updates

Continue editing this project and check changes in the local playground. Record the changes in CHANGELOG.md, then publish a new version:

# Small fixes: 0.1.1 → 0.1.2
npm version patch --no-git-tag-version
npm publish

npm publish runs syntax checks, the build, drawing tests, and TypeScript checks through prepack. The public package contains only the built library, declarations, and documentation. The playground and research files are excluded.

Use npm version minor --no-git-tag-version for a new feature release. Published versions cannot be overwritten; consumers choose when to upgrade:

npm install sexy-af@latest

Publishing is a deliberate release step; editing the local project does not automatically change installed copies.