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

@jsxtools/rollup-plugin-cem

v0.7.0

Published

A Rollup, Rolldown, and Vite-compatible plugin for generating a Custom Elements Manifest file from the module graph.

Downloads

79

Readme

@jsxtools/rollup-plugin-cem

Generate Custom Elements Manifests from the TypeScript modules already passing through your build.

@jsxtools/rollup-plugin-cem is a Rollup, Rolldown, and Vite-compatible plugin for generating a Custom Elements Manifest. It pairs with @jsxtools/rollup-plugin-tsc, which exposes TypeScript program metadata through module metadata.

Highlights

  • Reads TypeScript AST metadata from @jsxtools/rollup-plugin-tsc instead of reparsing files.
  • Merges newly analyzed modules into an existing custom-elements.json manifest.
  • Exposes API state needed by external tools that inspect or validate generated manifests.
  • Supports include/exclude patterns for source-level control.
  • Re-exports analyzer plugins for Lit, FAST, Stencil, and GitHub Catalyst.
  • Works in Rollup-compatible plugin pipelines, including Rolldown and Vite.

Install

npm install --save-dev @jsxtools/rollup-plugin-cem @jsxtools/rollup-plugin-tsc typescript

Quick start

import { rollupPluginCem } from "@jsxtools/rollup-plugin-cem";
import { rollupPluginTsc } from "@jsxtools/rollup-plugin-tsc";

const tsc = rollupPluginTsc.getOutputOptions();

export default {
	output: {
		dir: tsc.outDir,
		format: "es",
	},
	plugins: [
		rollupPluginTsc(),
		rollupPluginCem({
			manifestFile: "dist/custom-elements.json",
		}),
	],
};

Place rollupPluginCem() after rollupPluginTsc() so the CEM plugin can read TypeScript AST metadata from compiled modules.

Options

| Option | Default | Description | | -------------- | --------------------------------- | ---------------------------------------------------------- | | workDir | . | Base directory used to resolve paths. | | rootDir | src | Source root for Rollup-derived directory defaults. | | distDir | dist | Output directory used when manifestFile is omitted. | | manifestFile | ${distDir}/custom-elements.json | Manifest file to read, merge, and write. | | include | ** | Glob pattern or patterns for source files to analyze. | | exclude | none | Glob pattern or patterns for source files to skip. | | modules | none | TypeScript SourceFile objects for programmatic analysis. | | plugins | none | Custom Elements Manifest analyzer plugins. |

When Rollup output options provide output.dir or output.preserveModulesRoot, those values are used as distDir and rootDir unless explicitly overridden.

Framework plugins

import { litPlugin, rollupPluginCem } from "@jsxtools/rollup-plugin-cem";

export default {
	plugins: [
		rollupPluginCem({
			plugins: [litPlugin()],
		}),
	],
};

Available re-exports include litPlugin, fastPlugin, stencilPlugin, catalystPlugin, and catalystPlugin2.

Building validation tools

This package does not ship validation rules or a validation plugin hook. Instead, it exposes the generated manifest, analyzed source files, and TypeScript compiler objects so separate tools can validate however they want.

Standalone CLIs can compose TscAPI, CemAPI, and analyzer plugins directly:

import { CemAPI, getSourceFileNameFromModulePath, getSourceFilesByFileName } from "@jsxtools/rollup-plugin-cem/api";
import { TscAPI } from "@jsxtools/rollup-plugin-tsc/api";

const tsc = new TscAPI();
tsc.init();

const cem = new CemAPI();
cem.init({ modules: tsc.getSourceFiles(), program: tsc.program, typeChecker: tsc.typeChecker });
await cem.generate();

const issues = await validateManifest({
	manifest: cem.manifest,
	program: cem.program,
	sourceFileNameFromModulePath: getSourceFileNameFromModulePath,
	sourceFilesByFileName: getSourceFilesByFileName(cem.sourceFiles),
	sourceFiles: cem.sourceFiles,
	typeChecker: cem.typeChecker,
});

if (issues.length) {
	console.error(issues.join("\n"));
	process.exit(1);
}

Rollup users can also write a separate validation plugin that reads meta.tsc metadata from modules and validates after rollupPluginCem() writes the manifest.

import fs from "node:fs/promises";
import { getSourceFileNameFromModulePath, getSourceFilesByFileName } from "@jsxtools/rollup-plugin-cem/api";

const validateCem = () => {
	const sourceFiles = [];
	let program;
	let typeChecker;

	return {
		name: "validate-cem",
		generateBundle() {
			for (const id of this.getModuleIds()) {
				const tsc = this.getModuleInfo(id)?.meta?.tsc;

				if (tsc?.sourceFile) sourceFiles.push(tsc.sourceFile);
				program ??= tsc?.program;
				typeChecker ??= tsc?.typeChecker;
			}
		},
		async writeBundle() {
			const manifest = JSON.parse(await fs.readFile("dist/custom-elements.json", "utf8"));
			const issues = await validateManifest({ manifest, sourceFiles, sourceFileNameFromModulePath: getSourceFileNameFromModulePath, sourceFilesByFileName: getSourceFilesByFileName(sourceFiles), program, typeChecker });

			if (issues.length) this.error(issues.join("\n"));
		},
	};
};

API

import { CemAPI, getSourceFileNameFromModulePath, getSourceFilesByFileName } from "@jsxtools/rollup-plugin-cem/api";

const cem = new CemAPI();

cem.init({
	modules: sourceFiles,
	program,
	plugins: [],
	typeChecker,
});

await cem.updateManifest();
await validateManifest({
	manifest: cem.manifest,
	program: cem.program,
	sourceFileNameFromModulePath: getSourceFileNameFromModulePath,
	sourceFilesByFileName: getSourceFilesByFileName(cem.sourceFiles),
	sourceFiles: cem.sourceFiles,
	typeChecker: cem.typeChecker,
});

Peer dependencies

  • rollup ^4.59.0 — optional for compatible hosts.

License

MIT-0