Unified Language Server
unified-language-server provides a framework for building language servers based on the unified ecosystem. It allows developers to create editor integrations that format and validate documents using existing unified processors like remark (for Markdown) or rehype (for HTML). The current stable version is 4.0.1, with minor releases typically focusing on dependency updates and bug fixes, and major versions introducing breaking changes such as Node.js version requirements or significant internal refactors (e.g., using `unist-util-lsp`). Key differentiators include its tight integration with `unified-engine` for configuration file support (like `.remarkrc`) and its ability to work with any unified processor, simplifying the creation of LSP-compliant tools for AST transformations. It supports features like document formatting, validation, and quick fixes.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to `require()` an ESM-only package.fixChange `const { createUnifiedLanguageServer } = require('unified-language-server');` to `import { createUnifiedLanguageServer } from 'unified-language-server';` and ensure `"type": "module"` is set in your `package.json`. -
Error: Cannot find module 'remark' from '/path/to/language-server'
cause The specified `processorName` (e.g., 'remark') is not installed in the environment where the language server is executing.fixEnsure the processor package (e.g., `remark`) is listed in your language server's `dependencies` and run `npm install`. -
TypeError: options.defaultProcessor is not a function
cause `defaultProcessor` was passed an incorrect value or the imported processor is not the expected `unified` function.fixVerify that `defaultProcessor` receives a valid `unified` processor instance (e.g., `remark`) and that its named export is correctly imported (e.g., `import { remark } from 'remark';`). -
Language server failed to initialize: Configuration option 'requireConfig' is not recognized.
cause Using an outdated client or language server definition that doesn't recognize newer configuration options.fixEnsure both the `unified-language-server` package and the editor client integration are updated to their latest versions to support all configuration features.
Warnings
- breaking Support for Node.js 12 was removed. Ensure your environment runs Node.js 16.0 or higher.
- breaking The package transitioned to ESM-only. CommonJS `require()` is no longer supported for importing `unified-language-server`.
- breaking Updated `unified-engine` dependency, which notably introduced support for YAML 1.2 in configuration files. This might affect how existing configuration files are parsed if they rely on older YAML features or if new YAML 1.2 syntax is introduced.
- breaking Refactored to use `unist-util-lsp` internally. While not a direct API change for most users, this signals significant internal architecture updates which could affect custom extensions or deep integrations.
- gotcha If `options.processorName` cannot be found locally in `node_modules`, a warning is shown. This can happen if the processor (e.g., `remark`) is not installed as a dependency in the workspace where the language server is running.
Install
-
npm install unified-language-server -
yarn add unified-language-server -
pnpm add unified-language-server
Imports
- createUnifiedLanguageServer
const { createUnifiedLanguageServer } = require('unified-language-server')import { createUnifiedLanguageServer } from 'unified-language-server' - remark
import remark from 'remark'
import { remark } from 'remark' - LanguageServerOptions
import { LanguageServerOptions } from 'unified-language-server'import type { LanguageServerOptions } from 'unified-language-server'
Quickstart
import { remark } from 'remark';
import { createUnifiedLanguageServer } from 'unified-language-server';
// Set the process title for easier identification in system monitors
process.title = 'my-remark-language-server';
// Create and start the language server
createUnifiedLanguageServer({
// Name of ignore files (e.g., '.remarkignore')
ignoreName: '.remarkignore',
// Field in package.json to look for configuration
packageField: 'remarkConfig',
// Prefix for plugin names (e.g., 'remark-lint-')
pluginPrefix: 'remark',
// Name of the RC file (e.g., '.remarkrc')
rcName: '.remarkrc',
// The package ID of the expected processor (e.g., 'remark')
processorName: 'remark',
// The specifier to get the processor on the resolved module (e.g., 'remark' for named export)
processorSpecifier: 'remark',
// Optional fallback processor if `processorName` isn't found locally
defaultProcessor: remark
});
console.log('Remark language server started. Waiting for client connection...');