A unified Language Server Protocol (LSP) proxy that intelligently combines the Svelte Language Server and TypeScript Language Server, providing comprehensive IDE support for Svelte applications with no client-side configuration complexity.
npm install -g svelte-proxy-lspnpm install --save-dev svelte-proxy-lspnpx svelte-proxy-lsp --stdioThis proxy acts as a transparent middleware between LSP clients and the actual language servers:
┌─────────────────────────────────────────────────────────┐
│ LSP Client │
│ (VS Code, Neovim, etc.) │
└─────────────────────┬───────────────────────────────────┘
│ LSP Protocol (Single Connection)
┌─────────────────────▼───────────────────────────────────┐
│ Svelte Proxy LSP │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ProxyServer │ │
│ │ │ │
│ │ ┌──────────────────┬─────────────────────────┐ │ │
│ │ │ Request Router │ Document Manager │ │ │
│ │ │ - Position │ - Parse .svelte │ │ │
│ │ │ Analysis │ - Track Changes │ │ │
│ │ │ - Service │ - Sync State │ │ │
│ │ │ Selection │ │ │ │
│ │ └──────────────────┴─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────┐ ┌─────────────────┐ │
│ │ Svelte │ │ TypeScript │ │
│ │ Language │ │ Language │ │
│ │ Server │ │ Server │ │
│ │ (Process) │ │ (Process) │ │
│ └────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
- Single LSP Interface: Clients connect to one proxy server instead of managing multiple LSP connections
- Intelligent Routing: Analyzes cursor position in
.sveltefiles to determine which server(s) to query - Dual Server Management: Spawns and manages both
svelte-language-serverandtypescript-language-serveras child processes - TypeScript Svelte Plugin Integration: Automatically configures the TypeScript server with the Svelte plugin for enhanced .svelte file support
- Response Merging: Combines results from both servers, deduplicates, and returns unified responses
- Document Sync: Keeps both servers synchronized with document changes
The proxy intelligently routes requests based on where your cursor is:
- Script blocks (
<script>tags): Routes to TypeScript Language Server - Template/markup: Routes to Svelte Language Server
- Style blocks (
<style>tags): Routes to Svelte Language Server - Document-wide operations: Queries both servers and merges results
- TypeScript/JavaScript: Full IntelliSense, type checking, refactoring in
<script>blocks with Svelte-aware TypeScript plugin - Svelte Template: Component completions, directive support, template syntax
- CSS/SCSS: Styling support in
<style>blocks - Cross-Service: Seamless experience switching between template and script
- Enhanced Svelte Support: TypeScript server understands Svelte component exports, props, and cross-file references
- ✅ Completions: Auto-complete with context-aware routing
- ✅ Hover Information: Type info and documentation
- ✅ Go to Definition: Navigate to symbols across files
- ✅ Find References: Find all symbol usages
- ✅ Signature Help: Function parameter assistance
- ✅ Document Symbols: Outline view with all symbols
- ✅ Code Actions: Quick fixes and refactorings
- ✅ Rename: Rename symbols across files
- ✅ Formatting: Code formatting support
- ✅ Diagnostics: Real-time error and warning reporting
# Using npx (no installation required)
npx svelte-proxy-lsp --stdio
# After global installation
svelte-proxy-lsp --stdio
# With socket
svelte-proxy-lsp --socket=5000
# With verbose logging for debugging
svelte-proxy-lsp --stdio --verbose
# With trace logging (most detailed)
svelte-proxy-lsp --stdio --trace
# Quiet mode (errors only)
svelte-proxy-lsp --stdio --quiet
# Custom log level
svelte-proxy-lsp --stdio --log-level=debug
# Show help
svelte-proxy-lsp --helpThe proxy supports configurable logging levels:
--verbose- Debug level logging (shows server startup, requests, etc.)--trace- Most detailed logging (includes all requests and responses)--quiet- Only shows errors--log-level=<level>- Set specific level:error,warn,info,debug,trace
Note: In --stdio mode (default), logging is automatically set to error level to avoid interfering with LSP communication. Use --verbose or --trace to override this for debugging.
Add to settings.json:
{
"svelte.enable": false,
"typescript.suggest.enabled": false,
"eslint.enable": false
}Then configure the proxy in your language client settings or use with a VS Code extension that points to:
node /path/to/svelte-proxy-lsp/dist/server.js --stdio
local lspconfig = require('lspconfig')
-- Custom LSP configuration for Svelte Proxy
lspconfig.svelteproxy = {
default_config = {
cmd = { 'node', '/path/to/svelte-proxy-lsp/dist/server.js', '--stdio' },
filetypes = { 'svelte', 'typescript', 'javascript' },
root_dir = lspconfig.util.root_pattern('package.json', 'svelte.config.js', '.git'),
settings = {},
},
}
-- Use the proxy
lspconfig.svelteproxy.setup{}(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("node" "/path/to/svelte-proxy-lsp/dist/server.js" "--stdio"))
:major-modes '(svelte-mode typescript-mode js-mode)
:server-id 'svelte-proxy-lsp))# Start the proxy server
node dist/server.js --stdio
# Test with a simple request (requires LSP client)
# The server will automatically spawn svelte-language-server and typescript-language-serversrc/
├── server.ts # Main entry point
├── proxy/
│ ├── ProxyServer.ts # Core proxy logic and request routing
│ └── LSPServerProcess.ts # Child process management for LSP servers
└── utils/
└── documentParser.ts # Svelte document parsing and region detection
- Manages the main LSP connection with clients
- Routes requests to appropriate child servers
- Merges and deduplicates responses
- Handles document lifecycle events
- Spawns and manages child LSP server processes
- Provides JSON-RPC communication interface
- Handles server lifecycle (start, stop, error recovery)
- Parses
.sveltefiles to identify script/template/style regions - Provides position-based routing decisions
- Tracks document changes and versions
pnpm build # Compile TypeScript
pnpm dev # Watch mode development
pnpm clean # Clean build artifacts
pnpm start # Start the proxy serverThe project includes comprehensive unit and integration tests:
# Run all tests (47 passing, 1 skipped)
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run specific test suites
pnpm test -- --testPathPattern="diagnostics"
pnpm test -- --testPathPattern="symbol-insertion"
pnpm test -- --testPathPattern="workspace-symbols"- Unit Tests: 26 tests covering document parsing and process management
- Integration Tests: 21 tests validating real LSP server interactions
- Test Features: TypeScript type processing, cross-file imports, diagnostics, completions, symbols
For manual testing:
# Start the proxy directly
npx tsx src/server.ts --stdio
# Or build and run
pnpm build && pnpm start --stdioThe proxy automatically detects and configures the underlying language servers. No additional configuration needed - it inherits the capabilities of both servers.
The proxy automatically finds language servers in this order:
svelte-language-serverviarequire.resolve()typescript-language-servervia PATH lookup
- Runtime: Node.js 16+
- Language Servers:
svelte-language-server@^0.16.14typescript-language-server@^4.3.3typescript-svelte-plugin@^0.3.40(automatically configured)
- LSP Protocol Implementation:
vscode-languageserver@^10.0.0- LSP protocol types and utilitiesvscode-jsonrpc@^9.0.0-next.8- Direct JSON-RPC communicationvscode-languageserver-protocol@^3.17.6- Protocol definitions
- Simplified Setup: One LSP connection instead of configuring multiple servers
- Unified Experience: Seamless language support across Svelte file regions
- No Dependencies: Uses existing, battle-tested language servers
- Smart Routing: Context-aware request routing for optimal performance
- Full Feature Support: All LSP capabilities from both underlying servers
MIT