Language Servers are the New Frameworks
When Svelte 3 launched in 2019, the top demanded feature was TypeScript support. And when TypeScript support was finally announced in 2020, the reception was ecstatic.
But the secret is - not much needed to change in Svelte’s core code. It simply added language tooling to its core responsibilities. Svelte already had TypeScript preprocessors for years - but it wasn’t considered to have “TypeScript support” until the VS Code extension shipped.
I think this is indicative of a broader trend:
In the Third Age of JavaScript, all frameworks will provide their own language servers.
By way of proof, you see this pattern emerging in other frameworks as well:
- Vetur is standard tooling for all Vue.js developers
- React strongly recommends ESLint checks to enforce the Rules of Hooks (this is probably an understatement; probably no React professional would trust themselves to write Hooks right without the ESLint checker today)
- Angular has the Angular Language Service (thanks Mike) and Ember is working on it (thanks Alex)
- Tailwind Labs’ first hire was Brad Cornes, who made the Tailwind IntelliSense plugin
- GraphiQL, Relay Compiler and Apollo VS Code can be regarded as language servers for GraphQL development
Linting, typing, always-running-compilation and other forms of write-time checks and optimizations are not new. In fact, when dev teams write unit tests and lint rules, they are essentially creating their own bespoke language server for their own app. What’s new is that giving realtime feedback is now a responsibility shared by frameworks. This standardization increases productivity both when starting a new project and moving between projects.
Why
The proximate reason this is a thing is simple: Cost.
IBM coined the term ”Shift Left” after finding that the earlier you catch errors, the cheaper they are to fix (Neil points out that this research goes as far back as Barry Boehm in the 1980s). If you arrange the software development lifecycle from left (design) to right (production), the idea is that if you shift your errors “left” then you’d save actual money by catching errors earlier (this is disputed — and finding proof is hard!).
Of course, the flip side of Cost is Developer Experience. Cost is what our bosses pay, DX is what we feel. And we always gravitate to tools that guide us down the pit of success.
You could translate this idea to modern terms:
And then plot the slow leftward shift of frameworks:
Remember I said cost was a proximate reason. I believe there’s a deeper, more fundamental reason.
Tom was Right (and still is)
In 2017, Tom Dale of the Ember core team observed the first part of this evolution, that Compilers are the New Frameworks.
My current “investment thesis” is that what we call web frameworks are transforming from runtime libraries into optimizing compilers. When it comes to eking performance out of hand-authored JavaScript and accompanying runtime libraries, we’ve reached the point of diminishing returns.
He was not only astoundingly right (Svelte is built from the ground up as a compiler) but this process is also not done (Next.js is arguably an optimizing compiler for React, but the React team itself is working on Selective Hydration and a hybrid client/server model). Every framework basically invents its own metalanguage (React, Svelte, ActiveRecord) to solve for developer experience under constraints of a more popular general purpose language, and this language will eventually want to be compiled.
I’m simply extending this train of thought to its natural conclusion: what we call web frameworks are transforming from runtime libraries, into optimizing compilers with first class language server support.
I don’t know how unique this observation is but it felt revelatory when I first realized it. After you observe the evolution of a few frameworks and developer platforms you start seeing the same movie play out over and over again. To offer better developer experience, you end up creating a language. A language needs a compiler. A compiler eventually wants a language server.
Sell the Shovels
Language servers do a lot of undifferentiated heavy lifting - file watching, processing, reporting, supporting plugins for every IDE, and so on. If we’re all going to be building language servers, why do we have to reinvent the wheel every time?
Naturally, if language servers are the new bar for frameworks, those who own the common rails for the language server layer will do very well. Microsoft first developed the Language Server Protocol for VSCode and standardized it in 2017. This was a generous move that ensured the protocol would work with non-Microsoft IDEs like Eclipse, IntelliJ and even vim, and non-Microsoft languages like Python. Because LSP is ironically language and tooling agnostic, you also greatly lower the barrier for entire generations of language and editor agnostic startups, like Sourcegraph and Kite.
Here’s my advice for anyone who wants to make their dev tools project successful: time to learn how language servers work.
Author’s note: Orta from the TS core team left a great comment with more resources to learn about LSPs from Anders Hejlsberg and a coming “Build Server Protocol”!
Note: this was 1/3 of the thesis of my second React Rally talk.
DX Circle is a new journal on Developer Tools, Developer Communities, and Investing in Developer Experience Startups. If you’d like to submit an article, let me know!