From cem
Configures cem serve for custom element development, including package setup, cem.yaml config for manifests, demos, import maps, CSS transforms, and server startup with live reload.
npx claudepluginhub bennypowers/cem --plugin cemThis skill uses the workspace's default tool permissions.
Configure and run `cem serve` to preview custom elements with live reload,
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Automates semantic versioning and release workflow for Claude Code plugins: bumps versions in package.json, marketplace.json, plugin.json; verifies builds; creates git tags, GitHub releases, changelogs.
Configure and run cem serve to preview custom elements with live reload,
auto-generated import maps, and interactive knobs.
Runtime imports must be in dependencies, not devDependencies. The import
map generator only resolves packages from dependencies.
{
"dependencies": {
"lit": "^3.0.0"
},
"devDependencies": {
"@pwrs/cem": "^0.9.0"
}
}
Create .config/cem.yaml with generate and serve sections:
generate:
files:
- elements/*/my-*.ts
output: custom-elements.json
designTokens:
spec: tokens/my-tokens.json
prefix: my-prefix
demoDiscovery:
fileGlob: elements/*/demo/*.html
urlPattern: /elements/:tag/demo/:demo.html
urlTemplate: /elements/{{.tag}}/demo/{{.demo}}/
serve:
transforms:
css:
include:
- "elements/**/*.css"
generate.files: globs for element source filesgenerate.output: manifest output pathgenerate.designTokens: DTCG token file and CSS custom property prefixgenerate.demoDiscovery: how to find and route demo filesserve.transforms.css.include: globs for CSS files to serve as JS modules (enables import styles from './el.css' with { type: 'css' })Demos are HTML partials, not full documents. No <!DOCTYPE>, <html>, or
<head>. Include inline <script type="module"> and <style> as needed.
The index.html demo is the default — keep it minimal (simplest possible usage).
Additional demos show specific features or variants.
Use <meta itemprop="name"> and <meta itemprop="description"> on non-index
demos for display in the dev server UI.
For demo authoring conventions, see the write-demos skill.
cem serve --rendering=chromeless strips the dev server UI, serving bare demo
HTML with import maps and transforms — ideal for browser-based testing with
Playwright or Puppeteer. Append ?rendering=chromeless to any demo URL for
per-request chromeless mode without restarting.
See the gen-tests skill for full test scaffolding with page objects against
chromeless demos.
cem generate
Verify demos appear without warnings. If you see "No URL configured for demo",
check that demoDiscovery.urlPattern uses URLPattern syntax (:param captures,
not regex).
cem serve
Default port is 8000. Use --port <n> to change.
Open http://localhost:8000. The UI should show element demos in the sidebar.
Check browser console for import errors — if a bare specifier fails, the
package needs to be in dependencies.
Move the package from devDependencies to dependencies and reinstall.
Delete the cached manifest and regenerate: rm custom-elements.json && cem generate
lsof -ti:8000 | xargs kill or use --port.
cem serve regenerates the manifest in the background on file changes. If the
background regen produces a smaller/empty manifest, ensure generate.files in
the config matches your source globs — the background regen uses the config,
not CLI args.