tailwind-lsp-adapter
v1.1.5
Published
LSP adapter for @tailwindcss/language-server enabling Claude Code compatibility
Maintainers
Readme
tailwind-lsp-adapter
LSP adapter for @tailwindcss/language-server that enables compatibility with Claude Code.
Why?
Claude Code's LSP client doesn't support several protocol methods that the Tailwind CSS Language Server requires:
client/registerCapability— dynamic capability registrationworkspace/configuration— server requests workspace settingswindow/workDoneProgress/create— progress reporting
Without this adapter, the Tailwind CSS Language Server fails to initialize because it relies on dynamic registration to set up completions, hover, and diagnostics.
Architecture
Claude Code ←→ tailwind-lsp-adapter ←→ @tailwindcss/language-server
↓
Intercepts and handles:
- client/registerCapability
- client/unregisterCapability
- workspace/configuration
- window/workDoneProgress/create
- $/progress notificationsThe adapter is a transparent stdio proxy. It:
- Patches the
initializerequest to advertise dynamic registration support - Intercepts server→client requests that Claude Code can't handle
- Responds to them on behalf of Claude Code
- Forwards everything else unchanged
Installation
Quick Install (Recommended)
# 1. Install dependencies
npm install -g @tailwindcss/language-server tailwind-lsp-adapter
# 2. Run automated setup
tailwind-lsp-adapter --setup
# 3. Enable LSP tools (add to ~/.zshrc or ~/.bashrc)
echo 'export ENABLE_LSP_TOOL=1' >> ~/.zshrc
source ~/.zshrc
# 4. Restart Claude Code and install the plugin
# In Claude Code, run:
# /plugin install tailwind-lsp-adapter@local-pluginsThe --setup command automatically:
- Creates the plugin structure in
~/.claude/plugins/ - Registers the local marketplace
- Updates Claude Code settings
Manual Installation
Step 1. Create the plugin structure:
mkdir -p ~/.claude/plugins/tailwind-lsp-adapter/.claude-plugin
cat > ~/.claude/plugins/tailwind-lsp-adapter/.claude-plugin/plugin.json << 'EOF'
{
"name": "tailwind-lsp-adapter",
"description": "Tailwind CSS language support via tailwind-lsp-adapter",
"version": "1.0.0"
}
EOF
cat > ~/.claude/plugins/tailwind-lsp-adapter/.lsp.json << 'EOF'
{
"tailwindcss": {
"command": "tailwind-lsp-adapter",
"extensionToLanguage": {
".css": "css",
".scss": "scss",
".html": "html",
".jsx": "javascriptreact",
".tsx": "typescriptreact",
".vue": "vue",
".svelte": "svelte",
".astro": "astro",
".php": "php"
}
}
}
EOFStep 2. Register the plugin in a local marketplace:
mkdir -p ~/.claude/plugins/.claude-plugin
cat > ~/.claude/plugins/.claude-plugin/marketplace.json << 'EOF'
{
"name": "local-plugins",
"owner": { "name": "local" },
"plugins": [
{
"name": "tailwind-lsp-adapter",
"source": "./tailwind-lsp-adapter",
"description": "Tailwind CSS language support via tailwind-lsp-adapter"
}
]
}
EOFStep 3. Add the marketplace to Claude Code settings (~/.claude/settings.json):
{
"extraKnownMarketplaces": {
"local-plugins": {
"source": {
"source": "directory",
"path": "~/.claude/plugins"
}
}
}
}Step 4. Install the plugin in Claude Code:
/plugin install tailwind-lsp-adapter@local-pluginsStep 5. Enable LSP tools and restart:
echo 'export ENABLE_LSP_TOOL=1' >> ~/.zshrc
source ~/.zshrcConfiguration
Environment Variables
| Variable | Description |
|----------|-------------|
| TAILWIND_LSP_COMMAND | Override the language server command (default: tailwindcss-language-server) |
| TAILWIND_LSP_ARGS | Override server arguments (default: --stdio) |
| LSP_ADAPTER_DEBUG | Set to 1 to enable debug logging |
Debug Logging
To troubleshoot issues, enable debug logging in your .lsp.json:
{
"tailwindcss": {
"command": "tailwind-lsp-adapter",
"extensionToLanguage": {
".css": "css",
".tsx": "typescriptreact"
},
"env": {
"LSP_ADAPTER_DEBUG": "1"
}
}
}Logs are written to:
- macOS/Linux:
/tmp/tailwind-lsp-adapter.log - Windows:
%TEMP%\tailwind-lsp-adapter.log
Supported LSP Features
Once installed, Claude Code gains Tailwind CSS intelligence:
- Diagnostics — errors and warnings after edits (invalid classes, conflicting utilities)
- Hover — full CSS output preview for Tailwind classes
Limitations
Claude Code's LSP client has limited protocol support compared to full IDEs like VS Code. The following features are not available even with this adapter:
| Feature | Status | Reason |
|---------|--------|--------|
| Completions | Not supported | Claude Code doesn't request completions from LSP servers |
| Color decorators | Not supported | Claude Code doesn't process textDocument/documentColor |
| Code Actions | Not supported | Claude Code doesn't request code actions |
| Go to Definition | Not supported | Claude Code doesn't use textDocument/definition |
| Document Links | Not supported | Claude Code doesn't process document links |
This adapter enables the Tailwind CSS Language Server to initialize successfully and provide the features that Claude Code does support (diagnostics and hover). For full Tailwind CSS IntelliSense, use VS Code or another editor with complete LSP support.
Tailwind CSS v4 Support
The adapter automatically detects Tailwind v4 projects that use the new CSS-first configuration.
How It Works
- Auto-detection: When initializing, the adapter searches for CSS files containing
@import "tailwindcss"or@import 'tailwindcss' - Priority order: Prefers common entry points (
src/index.css,src/app.css,src/styles.css) - Configuration: Sets
experimental.configFileto enable v4 language server features
Manual Override
If auto-detection doesn't find your entry point, set the environment variable:
export TAILWIND_CSS_ENTRYPOINT="src/styles/main.css"Supported Patterns
| Pattern | Example |
|---------|---------|
| CSS Import | @import "tailwindcss"; |
| CSS Import (single quotes) | @import 'tailwindcss'; |
How It Works
The adapter sits between Claude Code and the Tailwind CSS Language Server as a transparent stdio proxy:
On
initialize: Patches the client capabilities to advertisedynamicRegistration: truefor all relevant features, plusworkspace.configurationandwindow.workDoneProgresssupport.On
client/registerCapability: Accepts the registration, stores it internally, and sends a success response back to the server. Claude Code never sees this request.On
workspace/configuration: Returns sensible Tailwind CSS defaults (class attributes, lint settings, etc.) so the server can configure itself.On
window/workDoneProgress/create: Accepts the progress token silently.On
$/progressandwindow/logMessage: Absorbs these notifications to prevent Claude Code from receiving messages it can't process.Everything else: Passed through unchanged in both directions.
Building from Source
git clone https://github.com/CommerceMax/tailwind-lsp-adapter.git
cd tailwind-lsp-adapter
npm install
npm run build
# Test locally
node dist/index.jsSecurity
The adapter implements several security measures:
- Command validation: Only allows
tailwindcss-language-serveras the LSP command - Path validation: Prevents access to system directories (
/etc,/usr, etc.) - Safe execution: Uses
execFileSyncwith array arguments (no shell interpolation) - Secure logging: Debug logs use unique filenames with restrictive permissions (0600)
Related Issues
- Claude Code #16360 — Missing LSP protocol handlers (workspace/configuration, client/registerCapability, window/workDoneProgress/create)
- Agasper/CSharpLspAdapter — Inspiration: same pattern for C# LSP
- Helix #4986 — Tailwind CSS LSP dynamic registration issues in other editors
License
MIT
