Langium Language Engineering Tool
Langium is an open-source, TypeScript-based framework designed for language engineering, offering first-class support for the Language Server Protocol (LSP). It enables developers to create Domain-Specific Languages (DSLs) and low-code platforms with deep integration into environments like VS Code and Eclipse Theia. The current stable version is 4.2.2, with frequent minor releases occurring roughly monthly or bi-monthly, and major versions typically released annually. Key differentiators include its declarative grammar language (similar to Xtext but relying on TypeScript interfaces instead of EMF), a robust dependency injection system for extensibility, high performance powered by Chevrotain, and the ability to generate typed Abstract Syntax Trees (ASTs). Langium supports execution in both Node.js environments and web browsers, making it versatile for various language tooling needs.
Common errors
-
Cannot find module 'vscode-languageserver/node' or its corresponding type declarations.
cause The `vscode-languageserver` package, essential for LSP functionality, is not installed or incorrectly imported for a Node.js environment.fixInstall the package: `npm install vscode-languageserver vscode-languageserver-types vscode-languageserver-protocol`. Ensure you are importing `vscode-languageserver/node` for Node.js servers, or `vscode-languageserver/browser` for browser-based servers. -
TypeError: Cannot read properties of undefined (reading 'validation') (or similar access on a service property)
cause A Langium service, or a property within a service, has not been correctly registered in the dependency injection module or accessed before its initialization.fixVerify your `_module.ts` file correctly registers all necessary services (default and custom). Ensure that custom services that depend on `LangiumServices` are properly constructed, typically by accepting `services: YourLanguageServices` in their constructor. -
Error: Node.js version X.Y.Z is not supported. Langium requires >=20.10.0
cause The installed Node.js version is older than the minimum required by Langium.fixUpgrade your Node.js version to 20.10.0 or newer. Tools like `nvm` (Node Version Manager) can help manage multiple Node.js versions. -
Error: The Langium grammar 'MyLanguage' cannot be loaded. Ensure the grammar has been generated and compiled.
cause The `langium-cli` generation step has not been run, or the generated TypeScript files have not been compiled, meaning the grammar definition is not available at runtime.fixRun `npm run langium:generate` (or `npx langium generate`) to generate the grammar-related TypeScript files, then `npm run build` (or `tsc`) to compile them. Verify the `langium:generate` script in `package.json` points to the correct grammar file.
Warnings
- breaking Langium v4.0.0 introduced significant breaking changes. Projects upgrading from v3.x or older will require adaptation, especially around service exports, type definitions, and reference handling.
- breaking The generated type names for AST nodes changed from `<typeName>` to `<typeName>.$type` in v4.0.0. Additionally, `PrecomputedScopes` was renamed to `LocalSymbols` and `References#findDeclaration` to `findDeclarations` (which now returns an array).
- gotcha Langium requires Node.js version 20.10.0 or higher. Using older versions will lead to errors during installation or runtime.
- gotcha When overriding or extending default services via Langium's dependency injection (DI) modules, the property name for the custom service in your module must exactly match that of the default implementation. Mismatches will result in the default service being used or injection errors.
Install
-
npm install langium -
yarn add langium -
pnpm add langium
Imports
- startLanguageServer
const { startLanguageServer } = require('langium');import { startLanguageServer } from 'langium'; - NodeFileSystem
import { NodeFileSystem } from 'langium';import { NodeFileSystem } from 'langium/node'; - LangiumServices
import { ILangiumServices } from 'langium';import { LangiumServices, LangiumSharedServices, Module } from 'langium'; - createMyLanguageServices
import { createMyLanguageServices } from './my-language-module';
Quickstart
import { startLanguageServer, EmptyFileSystem, LangiumSharedServices } from 'langium';
import { NodeFileSystem } from 'langium/node';
import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';
// --- This part of the code is typically generated by `langium-cli` ---
// It sets up your language's grammar, parser, validator, and other services.
// For a runnable example, we'll mock a simple `createMyLanguageServices`.
interface MyLanguageServices {
// Define your language-specific service interfaces here
// e.g., validation: { MyLanguageValidator: MyLanguageValidator }
}
function createMyLanguageServices(context: {
connection?: ReturnType<typeof createConnection>;
fileSystem: EmptyFileSystem | NodeFileSystem;
}): { shared: LangiumSharedServices; MyLanguage: MyLanguageServices } {
// In a real Langium project, this would load your grammar and hook up
// the generated parser, linker, scope provider, etc.
// For this quickstart, we're providing a basic mock.
const connection = context.connection ?? createConnection(ProposedFeatures.all);
// Mimic the creation of default shared services
const shared = require('langium/lib/shared/shared-module').createDefaultSharedModule(context);
// Mimic the creation of language-specific services
const MyLanguage: MyLanguageServices = {}; // Empty mock for demonstration
connection.onInitialize(() => {
// In a real setup, capabilities would be dynamically provided by Langium
return {
capabilities: {
textDocumentSync: { openClose: true, change: 1 /* TextDocumentSyncKind.Full */ },
completionProvider: { resolveProvider: true, triggerCharacters: ['.'] },
hoverProvider: true
}
};
});
connection.onInitialized(() => {
connection.console.log('Mock Langium language server initialized for MyLanguage.');
});
return { shared, MyLanguage };
}
// ------------------------------------------------------------------
// Establish a connection for the language server.
// Langium typically uses Node's IPC to communicate with the VS Code client.
const connection = createConnection(ProposedFeatures.all);
// Create the shared and language-specific services.
// `createMyLanguageServices` would be imported from your generated module file (e.g., `./src/language-server/my-language-module.ts`).
// The NodeFileSystem is crucial for server-side file access.
const { shared, MyLanguage } = createMyLanguageServices({ connection, ...NodeFileSystem });
// Start the language server.
// This function handles the lifecycle of the LSP connection and dispatches requests
// to the services configured in `shared`.
startLanguageServer(shared);
// Listen for incoming LSP messages.
connection.listen();