LSP Integration
cem lsp. VS Code users can install the extension. Neovim/Zed users configure their LSP client to start cem lsp for HTML, Twig, PHP, JavaScript, and TypeScript files.
Configure the CEM Language Server Protocol integration for your editor to get intelligent autocomplete, hover documentation, and validation for custom elements.
Prerequisites
Install CEM first if you haven’t already.
What is LSP?
The Language Server Protocol provides a standard way to add language-specific features to any editor. The CEM language server analyzes your custom elements manifests to offer contextual autocomplete, hover documentation, go-to-definition, and other IDE enhancements for HTML, Twig, PHP, JavaScript, and TypeScript files. This includes HTML embedded in languages like PHP (e.g. WordPress themes) or in Twig templates (e.g. Drupal themes).
Features
All editors with LSP support get the same core features:
- ✅ Autocomplete - Tag names, attributes, slot names, and values
- ✅ Hover Documentation - Element and attribute documentation on hover
- ✅ Go-to-Definition - Jump to element source code
- ✅ Go-to-References - Find all usages of elements across your workspace
- ✅ Validation - Real-time error detection for slots, attributes, and tag names
- ✅ Quick Fixes - One-click typo corrections and import suggestions
- ✅ Workspace Symbols - Search and navigate elements project-wide
See Using LSP Features for detailed usage guides.
Editor Configuration
Neovim
For Neovim 0.12+’s native LSP configuration support, create ~/.config/nvim/lsp/cem.lua:
---https://bennypowers.dev/cem/
---
---`cem lsp` provides editor features for custom-elements a.k.a. web components
---
---Install with go
---```sh
---go install bennypowers.dev/cem
---```
---Or with NPM
---```sh
---npm install -g @pwrs/cem
---```
---
---@type vim.lsp.ClientConfig
return {
cmd = { 'cem', 'lsp' },
root_markers = { 'custom-elements.json', 'package.json', '.git' },
filetypes = { 'html', 'twig', 'php', 'typescript', 'javascript' },
-- Control debug logging via LSP trace levels
trace = 'off', -- 'off' | 'messages' | 'verbose'
}VS Code
Install the Custom Elements Language Server extension from the VS Code marketplace. The extension bundles the language server and provides configuration options.
Configuration options in settings.json:
{
"cem.lsp.executable": "", // Custom path (empty = use bundled)
"cem.lsp.trace.server": "off" // LSP trace level: "off" | "messages" | "verbose"
}Emacs
Depending on which LSP plugin you use, configure Emacs to run cem for HTML, JavaScript, and TypeScript files:
lsp-mode:
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("cem" "lsp"))
:major-modes '(html-mode twig-mode php-mode typescript-mode js-mode)
:server-id 'cem-lsp))eglot:
(add-to-list 'eglot-server-programs
'((html-mode twig-mode php-mode typescript-mode js-mode) . ("cem" "lsp")))Claude Code
Install CEM first if not already installed:
npm install -g @pwrs/cem # or
go install bennypowers.dev/cem@latestThen install the plugin:
/plugin marketplace add bennypowers/cem
/plugin install cemThe LSP activates automatically for HTML, TypeScript, and JavaScript files.
Bonus: The plugin also includes MCP server support. See MCP Integration for details.
Other Editors
Configure your LSP client to run cem lsp for file types html, twig, php, typescript, and javascript. The server communicates over stdio and follows the standard LSP specification.
Typical configuration elements:
- Command:
cem lsp - File types:
html,twig,php,typescript,javascript - Root markers:
custom-elements.json,package.json,.git - Transport: stdio
Verify Installation
After configuring your editor:
- Open an HTML file in your project
- Start typing a custom element tag name
- You should see autocomplete suggestions for your custom elements
If autocomplete doesn’t appear:
- Ensure you have a
custom-elements.jsonin your project (runcem generate) - Check your editor’s LSP logs for errors
- Try enabling verbose logging (see configuration section)
Debug Logging
Debug logging is controlled via the LSP standard $/setTrace notification. Most editors expose this through trace level settings:
"off"- No debug logging (default)"messages"- Basic debug logging"verbose"- Detailed debug logging
Consult your editor’s LSP plugin documentation for how to set trace levels.
Next Steps
- Using LSP Features - Learn how to use autocomplete, hover, and validation
- LSP Protocol Reference - Technical API details
- Getting Started - Create your first project