Dec 16th 2025
Mark Sujew, Dr. Miro Spönemann
Xtext, Langium, what next?
What we’ve learned from building large-scale language tooling with Langium and Xtext, and a first glimpse at a new high-performance language engineering toolkit.
Xtext 2.9 ships with a new generator architecture, which is described in the previous post. Even though there is no immediate urge to migrate an existing language to the new generator infrastructure, here is how to do it. Make sure to keep a copy of your old code in order to safely roll back in case something goes wrong. If you customized a lot or if you want additional functionality such as IDEA, Web or Maven support, it may be easier to create new plug-ins using the New Xtext Project wizard and then copy existing files over.
Core UI functionality that could be used for Eclipse, IDEA and Web editors, is extracted to a new plug-in <myLang>.ide.
As it is usually created by the New Xtext Project wizard, you have to create it manually when migrating.
<myLang><myLang>) > Refresh > Specific Resources > Specify Resources…This is only necessary when you have JUnit plug-in tests.
These should be moved into a separate plug-in <myLang>.ui.tests now.
Create the plug-in analogously to the ide plug-in above, and add a plug-in dependency to <myLang>.ui.
The new generator will by default generate <myLang>RuntimeModule, <myLang>StandaloneSetup and <myLang>UiModule in Xtend.
To avoid duplicate classes, convert the existing ones to Xtend by using Convert to Xtend from the context menu of the respective Java files.
If you have not changed anything in the initially generated workflow, you can replace it by something like this
// adapt name
module <myPlugin>.Generate`<MyLang>`
import org.eclipse.xtext.xtext.generator.*
import org.eclipse.xtext.xtext.generator.model.project.*
var rootPath = ".."
Workflow {
component = XtextGenerator {
configuration = {
project = StandardProjectConfig {
// replace with your base plug-in's name
baseName = "<myPlugin>"
rootPath = rootPath
runtimeTest = {
enabled = true
}
genericIde = {
enabled = true
}
eclipsePlugin = {
enabled = true
}
// only needed if you have plug-in tests
eclipsePluginTest = {
enabled = true
}
createEclipseMetaData = true
}
code = {
encoding = "UTF-8"
fileHeader = "/*n * generated by Xtext ${version}n */"
// preferXtendStubs = false
}
}
language = StandardLanguage {
// replace with your language’s qualified name
name = "`<myLang>`"
// needed when you import an Ecore model in the grammar
referencedResource = "platform:/resource/path/to/genmodel"
// needed when you import an Xcore model in the grammar
referencedResource = "platform:/resource/path/to/Xcore/model"
// replace file extensions here
fileExtensions = "myLang"
serializer = {
generateStub = false
}
}
}
}
The MWE2 workflow should run without errors. After that some plug-ins may have compile errors.
<myLang>.ui<myLang>.ide as a dependency and remove the Antlr contentassist packages from package exports.<myLang>.tests:<myLang>.tests. Fix compile errors with Organize Imports and remove the stale package import from the manifest.<myLang>.ui plug-in.<myLang>.ui.tests:<myLang>.ui.tests package.Compare the plugin.xml and plugin.xml_gen in the runtime and the UI project using the compare editor. We have harmonized the whitespaces in generated files, so the button Ignore Whitespace may help you track down the real differences you have to merge manually.
<myLang>.ide plug-in. If you see deprecation warnings in classes you customized, just redirect the deprecated imports from org.eclipse.xtext.ui.editor.syntaxcoloring.X to org.eclipse.xtext.ide.editor.syntaxcoloring.XXX. For the binding in the module, you might have to override bindIdeISemanticHighlightingCalculator instead.That is it, I hope you were successful. For further assist, ask us in the Xtext forum.
Jan is one of the founders of TypeFox. Specialized in IDE development and language engineering, he is a long-term committer to various open-source projects, such as Xtext, Xtend and Theia. Jan also initiated the visualisation projects Sprotty and FXDiagram.