Generate

  • Generates CEM files from source code using syntax analysis powered by go and tree-sitter.
  • Identifies custom elements, classes, variables, functions, and exports.
  • Supports elements written in idiomatic style using Lit and TypeScript, with a @customElement decorator, and @property decorators on class fields.
cem generate best supports LitElements written in idiomatic style with TypeScript decorators. There is rudimentary support for extends HTMLElement, but it is not a high priority for development. If you need something more specific open an issue.

Use JSDoc comments to add metadata to your element classes, similar to other tools. Add a description by separating the name of the item with -

  • @attr / @attribute — Custom element attributes
  • @csspart — CSS shadow parts
  • @cssprop / @cssproperty — Custom CSS properties
  • @cssstate — Custom CSS states
  • @demo — Demo URL
  • @deprecated — Marks a feature or member as deprecated
  • @event — Custom events dispatched by the element
  • @slot — Named or default slots
  • @summary — Short summary for documentation

See the test-fixtures directory for examples

  • Automatically detects <slot> elements and part attributes in your element’s render() template.
  • Merges slot and part information found in templates with any provided via JSDoc, ensuring comprehensive documentation in the generated manifest.
  • Deprecation and other metadata for slots and parts can be specified via YAML in HTML comments.
  • Supports documenting slots and parts inline in your template HTML using HTML comments with YAML blocks.
  • YAML comments are not necessary to detect slots and parts, but help in documenting them for your users.
<!--
  summary: The main slot for content
  description: |
    This slot displays user-provided content.
    Supports multiline **markdown**.
  deprecated: true
-->
<slot></slot>
<!-- slot:
       summary: Named slot summary
     part:
       summary: Part summary
-->
<slot name="info" part="info-part"></slot>

Supports CSS Custom Properties by scanning css files and css tagged-template-literals

  • Custom properties beginning with _ will be ignored (treated as “private”) e.g. var(--_private)
  • If you provide a Design Tokens Community Group format module (JSON) to cem via the --design-tokens flag, cem will add metadata from your design system to any matching css variables it finds in your elements
  • You can use jsdoc-like comment syntax before each var call to document your variables
:host {
  color:
    /**
     * custom color for use in this element
     * @summary color
     * @deprecated just use the `color` property
     */
    var(--custom-color);
  border:
    1px
    solid
    /** Border color of the element */
    var(--border-color);
}

cem generate supports documenting your elements’ demos by linking directly from JSDoc, or by configurable file-system based discovery.

Add demos directly to your element class or members with the @demo tag:

/**
 * @demo https://example.com/my-element-plain/
 * @demo https://example.com/my-element-fancy/ - A fancier demo with description
 */
@customElement('my-element')
class MyElement extends LitElement {
  // ...
}

Demos defined this way will always appear in your manifest for the element.

cem can automatically discover demos from your codebase based on your repository structure and configuration.

Configure demo discovery with the demoDiscovery key in your .config/cem.yaml file

sourceControlRootUrl: "https://github.com/your/repo/tree/main/"
generate:
  demoDiscovery:
    fileGlob: "demos/**/*.html"
    urlPattern: "demos/(?P<tag>[\w-]+)/(?P<demo>[\w-]+).html"
    urlTemplate: "https://example.com/elements/{tag}/{demo}/"

Demo discovery options:

OptionTypeDescription
fileGlobstringGlob pattern for discovering demo files.
sourceControlRootUrlstringCanonical public source control URL for your repository root (on the main branch).
urlPatternstringPattern for generating demo URLs, e.g. "demos/{tag}.html". {tag} is replaced by tag name.
urlTemplatestring(optional) Alternative URL template for demo links.

If you are planning to use cem in an npm or yarn monorepo, the best way for now is to create a new .config/cem.yaml file for each package you want to generate for, instead of using a top-level config file.

Root package.json:

{
  "scripts": {
    "generate": "npm run generate --workspaces"
  },
  "workspaces": [
    "./core",
    "./elements"
  ]
}

core/.config/cem.yaml:

generate:
  files:
    - './**/*.ts'

core/package.json

{
  "scripts": {
    "generate": "cem generate"
  }
}

elements/.config/cem.yaml:

generate:
  files:
    - './**/*.ts'

elements/package.json

{
  "scripts": {
    "generate": "cem generate"
  }
}

Generate a custom elements manifest from your files:

cem generate \
  "src/**/*.ts" \
  --design-tokens npm:@my-ds/tokens/tokens.json \
  --exclude "src/**/*.test.ts" \
  --output custom-elements.json

For npm projects you can use npx @pwrs/cem generate ....

The generate command does not support remote packages. To inspect a remote package’s manifest, use the cem list command.
ArgumentTypeDescription
<files or globs>positional (array)Files or glob patterns to include
--package, -pstringPath to a package directory.
--output, -ostringWrite the manifest to this file instead of stdout
--exclude, -earrayFiles or glob patterns to exclude
--no-default-excludesboolDo not exclude files by default (e.g., .d.ts files will be included unless excluded explicitly)
--design-tokensstringPath or npm specifier for DTCG-format design tokens
--design-tokens-prefixstringCSS custom property prefix for design tokens
--demo-discovery-file-globstringGlob pattern for discovering demo files
--demo-discovery-url-patternstringGo Regexp pattern with named capture groups for generating canonical demo urls
--demo-discovery-url-templatestringURL pattern string using {groupName} syntax to interpolate named captures from the URL pattern
--source-control-root-urlstringGlob pattern for discovering demo files
--project-dirstringDeprecated: Use --package instead.

By default, some files (like .d.ts TypeScript declaration files) are excluded from the manifest. Use --no-default-excludes if you want to include all matching files and manage excludes yourself.