How I Got 2-3x Better Code from Claude Code with LSP Plugins
I kept getting frustrated. Claude Code would generate code that looked perfect, but when I ran it—boom—type errors, missing imports, and failing tests.
Me: "Write a UserService class"Claude: *generates code*Me: *runs code*Result: TypeError: Cannot read property 'id' of undefinedMe: "Fix this error"Claude: *fixes*Me: *runs again*Result: Another error...This back-and-forth debugging loop was eating up my time. Then I discovered two techniques that changed everything.
The Problem: Claude Can’t See What It Can’t Check
When Claude writes code, it’s making educated guesses. Without feedback, it can’t know if:
- A type annotation is wrong
- An import is missing
- A function signature changed
- A test is failing
I was treating Claude like a human developer who can run code and see results. But Claude doesn’t automatically run anything—you have to tell it to.
Solution 1: LSP Plugins (The Game Changer)
Language Server Protocol plugins give Claude real-time diagnostics after every file edit. This is like giving Claude an IDE’s red squiggly lines.
I installed the TypeScript LSP plugin:
/plugin install typescript-lsp@claude-plugins-officialNow after every edit, Claude receives automatic diagnostics:
Diagnostic: Parameter 'data' implicitly has an 'any' type. at src/services/UserService.ts:15
Diagnostic: Module '"./types"' has no exported member 'UserDTO'. at src/services/UserService.ts:2Claude sees these errors immediately and fixes them—no manual intervention needed.
Available LSP Plugins
# TypeScript/JavaScript/plugin install typescript-lsp@claude-plugins-official
# Python/plugin install pyright-lsp
# Rust/plugin install rust-analyzer-lsp
# Go/plugin install gopls-lspThe TypeScript plugin from @claude-plugins-official is the most battle-tested. Start there if you’re unsure.
Solution 2: Self-Checking Prompts
LSP plugins catch syntax and type errors. But what about logic errors? Test failures?
The fix: include verification commands directly in your prompts.
Before (No Self-Checking)
Write a function to process user dataClaude writes code, I run it, it breaks, I explain the error, Claude fixes it… repeat.
After (With Self-Checking)
Write a function to process user data. After writing, run:1. npx tsc --noEmit2. npm test -- --testPathPattern=processUserData
Fix any errors that appear.Now Claude runs the checks, sees failures, and fixes them—all without me stepping in.
Why This Works: The 2-3x Improvement
Boris Cherny (Claude Code creator) confirmed that self-checking alone delivers a 2-3x quality improvement. Here’s why:
┌─────────────────┐ │ Claude writes │ │ code │ └────────┬────────┘ │ ┌──────────────┴──────────────┐ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ LSP provides │ │ Tests provide │ │ type errors │ │ logic errors │ └────────┬────────┘ └────────┬────────┘ │ │ └──────────────┬──────────────┘ │ ▼ ┌─────────────────┐ │ Claude sees │ │ specific errors │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Claude fixes │ │ autonomously │ └─────────────────┘Without these feedback loops, Claude is flying blind. With them, Claude becomes a self-correcting system.
Common Mistakes I Made
Mistake 1: Skipping LSP Installation
I thought Claude would catch everything natively. Wrong. Claude benefits enormously from external tools—it’s not cheating to give Claude help.
Mistake 2: Vague Self-Check Instructions
Make sure it worksClaude can’t act on “make sure it works.” Be specific:
Run npx tsc --noEmit and npm testMistake 3: Wrong LSP Source
I tried a third-party LSP plugin first—it had compatibility issues. Stick with @claude-plugins-official.
Mistake 4: Not Updating Prompt Templates
My old prompts didn’t include test commands. I was wasting the self-check benefit. Now I add verification steps to every prompt template.
Practical Examples by Language
TypeScript
Create a UserService class with methods:- createUser(data: UserDTO): Promise<User>- findUser(id: string): Promise<User | null>- updateUser(id: string, data: Partial<UserDTO>): Promise<User>
After implementation, run:1. npx tsc --noEmit2. npm test -- --testPathPattern=UserService
Fix any type errors or test failures.Python
Implement a data processing pipeline that:1. Reads CSV files from a directory2. Validates each row against a schema3. Transforms and outputs to JSON
Run these checks after:1. pyright src/2. pytest tests/ -v
Address any type errors or failing tests.Rust
Create a CLI tool that parses command-line arguments and processes files.
Verification steps:1. cargo check2. cargo test3. cargo clippy -- -D warnings
Fix all errors and warnings before completing.Go
Build an HTTP handler for user registration with validation.
Run after implementation:1. go build ./...2. go test ./... -v3. go vet ./...
Ensure all checks pass.The Combination Effect
LSP plugins catch errors at edit time. Self-checking catches errors at test time. Together:
┌─────────────────┬───────────────┬───────────────┐│ Error Type │ LSP Plugin │ Self-Check │├─────────────────┼───────────────┼───────────────┤│ Type mismatch │ ✓ Caught │ ✓ Caught ││ Missing import │ ✓ Caught │ ✓ Caught ││ Syntax error │ ✓ Caught │ ✓ Caught ││ Logic error │ ✗ Missed │ ✓ Caught ││ Test failure │ ✗ Missed │ ✓ Caught ││ Runtime error │ ✗ Missed │ ✓ Caught │└─────────────────┴───────────────┴───────────────┘LSP is instant. Self-checking takes longer but catches more. You need both.
Getting Started
- Install the LSP plugin for your language
- Add verification commands to your prompt templates
- Watch Claude fix errors automatically
The first time you see Claude catch and fix its own error without you saying a word—magic.
Me: "Write a UserService class. Run tsc and npm test after. Fix any errors."Claude: *generates code*Claude: *runs tsc*Claude: *sees error*Claude: *fixes error*Claude: *runs tests*Claude: *all pass*Me: *impressed silence*Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments