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

@ngrok/mantle-vite-plugins

v1.0.0

Published

Vite plugins for @ngrok/mantle.

Readme

@ngrok/mantle-vite-plugins

Vite plugins for apps built with @ngrok/mantle.

Requirements

  • Node.js 24+
  • Vite 5+
  • @ngrok/mantle installed in the same project

Installation

pnpm add -D -E @ngrok/mantle-vite-plugins

Plugins

mantleTwSourcePlugin

Scans your app's source files for @ngrok/mantle/* component imports and injects Tailwind CSS @source directives into your global CSS file for only those components — so Tailwind only scans the mantle components your app actually uses, reducing generated CSS bundle size with no manual maintenance.

When to use

Mantle ships source-all.css as the zero-configuration option — a single @source that covers every component in the package:

@import "@ngrok/mantle/mantle.css";
@import "@ngrok/mantle/source-all.css";

Use mantleTwSourcePlugin instead when your app uses a subset of mantle components and you want the smallest possible CSS output. The plugin scans your source files, detects which components you import, and writes targeted @source directives for only those components.

| Approach | When to use | | ---------------------- | ------------------------------------------------------------------------------------------ | | source-all.css | Your app uses most or all mantle components, or you want zero build tooling configuration. | | mantleTwSourcePlugin | Your app uses a subset of mantle components and you want the smallest possible CSS output. |

If you are unsure, start with source-all.css.

Setup

1. Add the plugin to vite.config.ts:

import { mantleTwSourcePlugin } from "@ngrok/mantle-vite-plugins";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [mantleTwSourcePlugin()],
});

2. In your global CSS, import mantle.css without source-all.css:

@import "tailwindcss";
@import "@ngrok/mantle/mantle.css";
/* do NOT add @import "@ngrok/mantle/source-all.css" */

That is all. The plugin writes the correct @source lines into your CSS file before @tailwindcss/vite processes it.

Options

| Option | Type | Default | Description | | ----------- | ---------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | include | string[] | ["app"] | Directories to scan recursively for @ngrok/mantle/* imports. Paths are relative to the Vite project root. | | cssFile | string | First of app/global.css, src/global.css, app/app.css, src/app.css that exists | Path to the CSS file to inject @source directives into. Relative to the Vite project root, or absolute. | | allowlist | string[] | [] | Component names to always include regardless of scanner detection. Accepts PascalCase ("AlertDialog") or kebab-case ("alert-dialog"). Useful for runtime-only components. |

How it works

  1. configResolved — After Vite resolves its configuration, the plugin locates @ngrok/mantle's dist/ directory by walking up the directory tree from the project root to find node_modules/@ngrok/mantle (using the symlink path rather than the pnpm content-addressed realpath, so generated paths stay clean). In dev mode, it also seeds its known-component set from any existing @source block so styles are present for all previously-visited routes immediately after a restart. It then walks the directories in include scanning every .ts, .tsx, .js, .jsx, .mdx, and .md file for @ngrok/mantle/<name> import statements and writes a clearly-marked block of @source directives directly into the target CSS file on disk, immediately after the last @import line. The write is idempotent — the file is only touched when the content would actually change.

  2. resolveId — The plugin intercepts every @ngrok/mantle/<name> import that Vite actually resolves during the session. This is module-graph-aware and catches imports the directory scan misses: components imported from workspace packages outside include, and transitive mantle-internal imports (e.g. a component that internally imports another mantle component). In dev mode, newly-seen components trigger a debounced CSS write. In production, the full set is written in closeBundle.

  3. closeBundle — At the end of a production build, the plugin writes the precise set of components from the directory scan, resolveId intercepts, and allowlist — no prior-run knowledge is included, so removing a component from the app will shrink the CSS on the next build. SSR builds are skipped entirely: in SSR double-build setups (e.g. React Router), the server build resolves fewer components than the client build, and writing during it would overwrite the correct client-built set with a reduced one.

  4. configureServer — In development, the plugin also watches your source files via Vite's built-in file watcher. When a file change introduces a mantle import for a component not previously detected, the CSS file is updated in place and Tailwind's own watcher picks up the change automatically — no server restart required.

Why write to disk: @tailwindcss/vite reads CSS files from disk at dev-server startup to initialize its file-system scanner and set up watchers, before Vite's transform pipeline runs. Injecting @source via a transform hook works in production builds but is invisible to Tailwind's dev-mode scanner. Writing to disk ensures the directives are present when Tailwind first reads the file.

The generated block

The plugin writes a deterministic, human-readable block that is safe to commit:

@import "tailwindcss";
@import "@ngrok/mantle/mantle.css";

/* @ngrok/mantle-vite-plugins:source:start */
@source "../node_modules/@ngrok/mantle/dist/button.js";
@source "../node_modules/@ngrok/mantle/dist/button-*.js";
@source "../node_modules/@ngrok/mantle/dist/input.js";
@source "../node_modules/@ngrok/mantle/dist/input-*.js";
/* @ngrok/mantle-vite-plugins:source:end */

To remove it, delete the lines between the source:start and source:end markers, or remove the plugin from your Vite config and it will be cleaned up on the next build.

TypeScript

Type declarations are included. No @types/* package is needed.