Rider is a cross-platform .NET IDE. While all language-related features discussed in this guide can be run by Rider in a ReSharper background process, the actual IDE frontend is based on the IntelliJ platform. The ReSharper backend is either running on the .NET Framework on Windows, and .NET Core or Mono on Mac or Linux. The frontend, however, is running on the JVM. In order to make those two processes talk with each other and let them share data, some kind of protocol is required. For instance, the frontend might need to tell the ReSharper process that we hit Tab after a
value., and that auto-completion items should be calculated. In return, the background process needs to share all the possible items with the frontend, so that the user can choose from a list. This protocol is implemented using Kotlin.
As an author of a ReSharper extension, we might want to make it available for Rider as well. Depending on the types and extension points we are using, this sometimes doesn't require so much additional work, but only to create a Rider plugin project and to follow Rider's plugin packaging. This is usually true if we:
Don't use any XAML option pages or tool windows
Don't use any VisualStudio components
In all other cases, we would need to re-implement missing parts using the IntelliJ Platform SDK, which is structured similar to this guide. For inter-process communication, we can easily extend the protocol using a Kotlin DSL.
Plugin project (.NET)
The standard approach of migrating an existing ReSharper plugin to also work for Rider, is to copy the existing CSPROJ file and adapt the package reference from
We could name these two project files
MyPlugin.RD.csproj, which is great for code sharing. Unfortunately, this won't play well when executing MSBuild on them, because both projects would share the same
project.assets.json file. A simple solution to fix this is to put a custom
Directory.Build.props file besides the two project files:
This will provide MSBuild with an individual OBJ and BIN folder both the ReSharper and Rider project.
Rider plugins are simple ZIP archives containing metadata about the plugin, ReSharper extensions (DLL) and/or IntelliJ extensions (JAR). The content is structured like this:
+ plugin-root-folder + META-INF - plugin.xml + lib - plugin.jar + dotnet - plugin.dll
Among other declarations, the
plugin.xml must provide common metadata about its id, name, version, and frontend dependencies:
For simple plugins that don't contain code that is specific to Rider, we might choose to manually pack the archive. However, this requires us to also manually update the
idea-versiontag according to the About JetBrains Rider dialog. Also note that archives created using .NET capabilities (like
System.IO.Compression or PowerShell's
Compress-Archive) might not work.
For more complex plugins as well as for better testability, it is recommended to have a dedicated gradle build. This will also automatically take care of updating the
Plugin project (JVM)
The recommended solution for building Rider frontend plugins is to use the gradle-intellij-plugin. This usually involves two files
settings.gradle we define the project name and other global data:
build.gradle we basically use and extend the
intellij task provided from the gradle plugin. Here is an example:
For more information about building IntelliJ plugins, please see the IntelliJ Platform SDK.
Rider has an extensible protocol to allow communication between IntelliJ frontend and ReSharper backend. This requires our plugin to implement a data model that can be used on .NET and JVM side. For our convenience, the IntelliJ gradle plugin allows to generate these implementations from a Kotlin base definition. Here is an example:
To generate the Kotlin and C# model implementation from that, we need to extend our
build.gradle file. At the start we need to add a dependency for
Then we can define our own
Using the gradle-intellij-plugin, we can easily launch an experimental Rider installation with our plugin installed right away. We can either start the
runIde task from the Gradle tool window inside IntelliJ IDEA, or execute
gradlew :runIde from the command-line.