# Manifest generators compared

> How the manifest option compares with the Custom Elements Manifest analyzer, cem and Lit's gen-manifest, row by row, from running all four on one component library.

Pick the tool that writes your `custom-elements.json`, by what each one reads from your components and where its paths point. Skip this page if you only want to turn the plugin’s [`manifest`](/guides/manifest/) option on.

Every cell below comes from running the four tools on one small Lit library in October 2026: an element that extends a mixin over a base class, with decorators, JSDoc, a constructor, dispatched events, a vanilla element and a barrel file. The versions were Lit DevTools 0.24, [`@custom-elements-manifest/analyzer`](https://custom-elements-manifest.open-wc.org/analyzer/getting-started/) 0.11.0 with `--litelement`, [`cem`](https://bennypowers.dev/cem/) 0.11.4 and [`@lit-labs/gen-manifest`](https://github.com/lit/lit/tree/main/packages/labs/gen-manifest) 0.3.6 through `lit labs gen --manifest`. Follow the links for their current state.

## At a glance

|                                           | Lit DevTools                                            | [CEM analyzer](https://custom-elements-manifest.open-wc.org/analyzer/getting-started/) | [cem](https://bennypowers.dev/cem/)              | [Lit gen-manifest](https://github.com/lit/lit/tree/main/packages/labs/gen-manifest) |
| ----------------------------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------- |
| Runs as                                   | Vite plugin option, `lit-devtools manifest`             | CLI, or `create()` in the browser                                                      | CLI (a Go binary on npm)                         | `lit labs gen --manifest`                                                           |
| Schema version written                    | 2.1.0                                                   | 1.0.0                                                                                  | 2.1.0                                            | 1.0.0                                                                               |
| Module paths                              | The built files under `vite build`, else source         | Source (`src/x.ts`)                                                                    | Source, renamed to `.js`                         | The tsconfig `outDir` (`out/x.js`)                                                  |
| `@property()` attribute and `reflects`    | Yes, but lost on a class that extends a mixin           |                                                                                        |                                                  |                                                                                     |
| Types                                     | As written; the `type:` option when unannotated         | As written                                                                             | As written                                       | From the type checker                                                               |
| `@state()` and private members            | Left out                                                | Listed, with `privacy`                                                                 | Private listed, `@state()` left out              | Listed, with `privacy`                                                              |
| Methods, with parameters and return type  | Yes; the return type came out empty                     | Yes, without the `@returns` description                                                |                                                  |                                                                                     |
| `render()` and `@internal` methods        | Left out                                                | Left out                                                                               | Listed                                           | Listed                                                                              |
| Events from `@fires`                      |                                                         |                                                                                        |                                                  |                                                                                     |
| Events from `this.dispatchEvent(…)`       | Yes, literal names only                                 | Yes, and one named after a variable                                                    |                                                  |                                                                                     |
| Defaults set in the constructor           |                                                         |                                                                                        |                                                  |                                                                                     |
| Slots, parts, CSS custom properties       |                                                         |                                                                                        |                                                  |                                                                                     |
| CSS states (`@cssstate`)                  |                                                         |                                                                                        |                                                  |                                                                                     |
| `@attr`, `@prop`, `@default`, `@tag` tags | `@attr` and `@default`                                  |                                                                                        |                                                  |                                                                                     |
| Inherited members, marked `inheritedFrom` | Yes, across modules, mixins and dependencies’ manifests |                                                                                        |                                                  |                                                                                     |
| Mixin declarations                        |                                                         |                                                                                        |                                                  |                                                                                     |
| A vanilla `HTMLElement` element           |                                                         |                                                                                        |                                                  |                                                                                     |
| `observedAttributes`                      |                                                         |                                                                                        |                                                  |                                                                                     |
| Barrel files (`export * from`)            | Resolved to each name, through chains of barrels        | Listed as a `*` export                                                                 | Resolved to each name                            | Resolved to each name                                                               |
| Watch mode                                | The dev server, through HMR and a file watcher          | `--watch`                                                                              | `--watch`                                        | No option                                                                           |
| Also does                                 | The same docs in the DevTools panel and Lit Inspector   | A plugin API; FAST, Stencil and Catalyst                                               | A language server, MCP, a dev server, `validate` | React and Vue wrappers                                                              |

## CEM analyzer

The analyzer is the reference most tools read against, and it reads the widest syntax, frameworks beyond Lit included, through plugins. It lists private members and internal state with their `privacy`, so a reader that wants the public API filters them out. Its paths name your source files, so a published package needs a plugin to point them at the built ones.

## cem

`cem` writes schema 2.1 and comes with tooling built on the manifest: a language server, an MCP server, a dev server and a validator. On our library it read decorated properties well on an element that extends `LitElement`, but not on one that extends a mixin call. It doesn’t merge inherited members, infer dispatched events or read constructor defaults.

## Lit’s gen-manifest

The Lit Labs generator runs the TypeScript checker, so it reports types you never wrote, such as `string` for a parameter that defaults to `'info'`. Its paths follow your tsconfig’s `outDir`. It lists lifecycle and `@internal` methods and doesn’t merge inherited members. It is experimental, like the rest of Lit Labs.

## Lit DevTools

The plugin reads your components the way its DevTools panel does, so the manifest, the panel and Lit Inspector show the same docs. Under `vite build` its paths name the files you ship, and tree-shaken components are left out. In dev the manifest follows every edit. Its types are the text you wrote, and the table’s “No” rows are what it doesn’t read yet.

## Related

[Publish a Custom Elements Manifest](/guides/manifest/)Turn the manifest option on and keep a copy in your package.

[Compared to alternatives](/overview/compare/)How the plugin's hot reloading compares with other tools.
