Coding Challenge #99 - Language Server (LSP)
This challenge is to build your own language server and learn the language server protocol.
Hi this is John with this week’s Coding Challenge.
🙏 Thank you for being one of the 90,390 software developers who have subscribed, I’m honoured to have you as a reader. 🎉
If there is a Coding Challenge you’d like to see, please let me know by replying to this email📧
Coding Challenge #99 - Language Server (LSP)
This challenge is to build your own Language Server, implementing the Language Server Protocol.
What is the Language Server Protocol?
Adding features like auto complete, go to definition, or documentation on hover for a programming language takes a lot of work. Traditionally this work was done by each tool developer, for each programming language their tool supported.
That’s a lot of duplicated work! Enter the idea of a Language Server and the Language Server Protocol.
The goal of the Language Server Protocol (LSP) is to provide a standardised mechanism for language servers and development tools to communicate. Then a single Language Server can be re-used in multiple development tools. The development tools can then in turn can support multiple languages with minimal effort.
LSP is a win for both language providers and tooling vendors because of the reduced effort. It’s a win for us as software engineers as we can use the same language server across tools and see more consistency in our tooling.
📌 Next Systems Programming (Redis) Course Starts 20th October
Would you like to build a network server from scratch with me?
Learning about network programming, concurrency, testing, and systems software development?
If so check out my course: Build A Redis Server Clone: Master Systems Programming Through Practice.
It is designed to be intense! It’s 11 hours of instructor-led time over two weeks. With the goal of having you build a clone of the original Redis server by the end of the two weeks.
If you sign up before 6th October you can get $100 off using the code: EARLYBRO25
If You Enjoy Coding Challenges Here Are Four Ways You Can Help Support It
Refer a friend or colleague to the newsletter. 🙏
Sign up for a paid subscription - think of it as buying me a coffee ☕️, with the bonus that you also get 20% off any of my courses.
Buy one of my self-paced courses that walk you through a Coding Challenge.
Join one of my live courses where I personally teach you Go by building five of the coding challenges or systems software development by building a Redis clone.
The Challenge - Building A Language Server That Implements The Language Server Protocol.
In this Coding Challenge you’re going to build your own Language Server, implementing the Language Server Protocol and performing some analysis of the document currently being edited.
For this Coding Challenge you’re going to add support for some Language Features. In LSP, Language Features provide the actual smarts in the language server protocol. They are usually executed on a [text document, position] tuple. The main language feature categories are:
code comprehension features like Hover or Goto Definition.
coding features like diagnostics, code complete or code actions.
To give you a feel for what is possible and how to do it in this Coding Challenge you’ll be implementing some basic diagnostics and code completion.
Step Zero
To get started, pick your programming language of choice and create a new project. Whilst language servers can support multiple communication channels, for this project I suggest you focus on stdio.
Once you have a project ready to start development you’ll also need some way to test your solution. I used this as a great excuse to install and learn neovim. Having installed noevim I opted to start with **kickstart.nvim.**
You can of course use a language server with other editors, see your environments documentation for how.
Step 1
In this step your goal is to create a language server that can startup, receive messages via stdio and respond to the initialise request.
To do so you’re going to need to create a command line program that start’s up, opens standard in and standard out, and is able to handle the serialisation and de-serialisation of JSON-RPC request, response and notification messages exchanged over stdio.
You should start by reading the overview of the LSP. Then the Basic JSON Structures in the LSP specification. After that read about the Server lifecycle, and implement enough of you LSP to handle the Initialize Request.
I strongly suggest you include logging in your language server so you can see what is happing, for example at this stage mine looks like:
[cclsp] CC LSP is running
[cclsp] Received method: initialize
[cclsp] Connected to: Neovim 0.11.4
[cclsp] Sent the reply
[cclsp] Received method: initializedIt’s not particular exciting, but you now have communication between the editor and the language server and are ready to start adding the more interesting features.
Step 2
In this step your goal is to handle the DidOpenTextDocument notification and the DidChangeTextDocument notification. Be sure to parse the messages and for now simply log the contents of the text document out. If you haven’t already you might need to add the relevant capabilities for text document synchronisation in the ServerCapabilities section of the response to the Initialize Request.
That might look something like this:
[cclsp] CC LSP is running
[cclsp] Received method: initialize
[cclsp] Connected to: Neovim 0.11.4
[cclsp] Sent the reply
[cclsp] Received method: initialized
[cclsp] Received method: textDocument/didOpen
[cclsp] Opened: file:///Users/john/cc/test.txt
This is a test documentStep 3
In this step your goal is to evaluate the document that has been opened or changed and provide some diagnostic information about it. As an example, for this I decided to evaluate text files and advocate for my belief that it’s better to learn by doing. To do that I looked for the phrases:
“Watching a Video” and where it was found, provided the feedback: “It’s much better to learn by doing! Try Coding Challenges instead.”
“Coding Challenges” and where it was found, provided the feedback: “This is the way!”
Viewed in neovim that looks like this:
Step 4
In this step your goal is to support Completion Requests. These are the requests that support code completion in your editor. In my solution I added support for the Completion Item “CodingChallenges” which looks like this in neovim:
You’ve now built the framework needed to implement a full language server, though there is obviously much more that is possible, just take a read through the rest of the specification!
Going Further
To take this project further you can work through the full specification adding support for all the notifications we didn’t look at.
Alternately, or as well, you can build a tool to analyse the document(s) for a programming language of your choice. If you don’t know where to start there, perhaps check out the build your own JSON parser coding challenge and then use that parser to build a language server for JSON.
P.S. If You Enjoy Coding Challenges Here Are Four Ways You Can Help Support It
Refer a friend or colleague to the newsletter. 🙏
Sign up for a paid subscription - think of it as buying me a coffee ☕️ twice a month, with the bonus that you also get 20% off any of my courses.
Buy one of my courses that walk you through a Coding Challenge.
Subscribe to the Coding Challenges YouTube channel!





Node.js + Express Roadmap for Beginners 2025
├── What is Node.js? Event-Driven & Non-Blocking I/O
├── NPM Modules & Package.json
├── Core Modules (fs, path, http)
├── Setting Up Express Server
├── RESTful APIs with Express (GET, POST, PUT, DELETE)
├── Mini Project: Simple Notes API
├── Middleware & Error Handling
├── Basic Authentication (JWT, Bcrypt)
├── Mini Project: Login/Signup API with JWT
├── Connecting to MongoDB using Mongoose
├── MVC Pattern in Backend
├── Mini Project: Blog API with CRUD Operations
├── Bonus: CORS, Rate Limiting, Deployment on Render
Frontend Skills:
- HTML, CSS, JavaScript
- Frameworks: React, Vue.js
- Responsive & Mobile-first Design
- Version Control: Git
Backend Skills:
- Languages: Java, Python, Node.js, PHP
- Databases: MySQL, MongoDB
- API Development & Microservices
- Security, Authentication & Authorization
DevOps & Tools:
- Docker & Kubernetes
- CI/CD pipelines: GitHub Actions, Jenkins
- Cloud Platforms: AWS, Azure
Full-Stack Power:
Bring it all together — frontend, backend, databases, and deployment.