Skip to content

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.

Frustrating cycle
Me: "Write a UserService class"
Claude: *generates code*
Me: *runs code*
Result: TypeError: Cannot read property 'id' of undefined
Me: "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:

Installing TypeScript LSP
/plugin install typescript-lsp@claude-plugins-official

Now after every edit, Claude receives automatic diagnostics:

LSP output example
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:2

Claude sees these errors immediately and fixes them—no manual intervention needed.

Available LSP Plugins

LSP plugins by language
# TypeScript/JavaScript
/plugin install typescript-lsp@claude-plugins-official
# Python
/plugin install pyright-lsp
# Rust
/plugin install rust-analyzer-lsp
# Go
/plugin install gopls-lsp

The 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)

Weak prompt
Write a function to process user data

Claude writes code, I run it, it breaks, I explain the error, Claude fixes it… repeat.

After (With Self-Checking)

Strong prompt with self-check
Write a function to process user data. After writing, run:
1. npx tsc --noEmit
2. 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:

Quality improvement flow
┌─────────────────┐
│ 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

Vague (useless)
Make sure it works

Claude can’t act on “make sure it works.” Be specific:

Specific (useful)
Run npx tsc --noEmit and npm test

Mistake 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

TypeScript prompt with self-check
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 --noEmit
2. npm test -- --testPathPattern=UserService
Fix any type errors or test failures.

Python

Python prompt with self-check
Implement a data processing pipeline that:
1. Reads CSV files from a directory
2. Validates each row against a schema
3. Transforms and outputs to JSON
Run these checks after:
1. pyright src/
2. pytest tests/ -v
Address any type errors or failing tests.

Rust

Rust prompt with self-check
Create a CLI tool that parses command-line arguments and processes files.
Verification steps:
1. cargo check
2. cargo test
3. cargo clippy -- -D warnings
Fix all errors and warnings before completing.

Go

Go prompt with self-check
Build an HTTP handler for user registration with validation.
Run after implementation:
1. go build ./...
2. go test ./... -v
3. 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 coverage matrix
┌─────────────────┬───────────────┬───────────────┐
│ 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

  1. Install the LSP plugin for your language
  2. Add verification commands to your prompt templates
  3. Watch Claude fix errors automatically

The first time you see Claude catch and fix its own error without you saying a word—magic.

The new cycle
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