I recently wrote my first article on my blog about my development experience with a cloud security plugin for JetBrains IDEs, especially IntelliJ IDEA. I want to share a guide on how you could dive into IDEA plugin development. To develop plugins for JetBrains IDE, you should have skills in Kotlin or Java, but solutions will mainly be made in Kotlin.
If you want to get a deeper knowledge across different aspects of plugin development, read my latest: IntelliJ IDEA Plugin Development: What Have I Learned
Diving deep into JetBrains IntelliJ IDEA plugin development
Developing a plugin for IDEs could be tricky, but the IntelliJ platform provides several ways to build your plugin from scratch.
One of the obvious steps in developing your first plugin is downloading and installing the proper IDE. For my Docker and Kubernetes Security plugin, I used IntelliJ Community because I don’t have a personal license for the Ultimate edition. You can easily download it from the official site.
After installing the IDE, you have two choices to start developing the plugin:
- Install the Plugin DevKit plugin and create a project with it. Install this plugin not only for the integrated plugin generator but also to highlight problems in your plugin.
- Clone IntelliJ platform plugin template and adjust it according to your needs.

Both ways provide you with a pre-configured project for easier development. After opening it, you must wait while all necessary dependencies are downloaded.
After importing the whole project, Gradle will have new internal tasks, but one of the most important tasks is running the plugin. It helps you run a new window IDE with the pre-installed plugin that you’re currently working on.
Running the Run plugin task is a way to test and debug your plugin, and you will run it a lot.
At this step, you’ve everything you need to create the first idea plugin in your life (or not).
Developing a plugin
The IntelliJ Platform is well documented, and on their site, you can find useful information their site. In this guide, I will tell you about the parts I constantly use in development.
As a developer, you have definitely seen how an IDE highlights some problems and offers quick fixes to resolve them. This mechanism is called Code Inspection and provides a tool for static code analysis.
For implementing your first code inspection, you should:
- Define your idea for code inspection.
- Create an inspection class by implementing LocalInspectionTool. That class will be the entry point for developing inspection logic.
- Inspection and analysis of targeted files were performed with special
Visitorclasses. Those classes provide a way to analyze the whole file or specific parts of the analyzed file. So, you should create one for your inspection. - If you want to provide a user with a way to fix the highlighted problem, you should implement
LocalQuickFix. - Write an inspection description in HTML format, and here, Plugin DevKit helps you. When you implement your inspection class, it will suggest creating HTML documentation. It is better to write inspection descriptions following UI guidelines for inspections.
- In case if you want to struggle less — make a tests, the platform provides already implemented solution to make tests easy. Just look at this testing documentation. Also read my previous article with testing chapter, automated tests saved a lot of time and nervous.
In general, some of the points are additional, but the base logic for your whole code inspection is to create a class by implementing LocalInspectionTool and overriding method build visitor that should return you Visitor with logic.
class SomeCodeInspection: LocalInspectionTool() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
// there is could be your logic
super.visitElement(element)
println("element: ${element.text}")
}
}
}
}Look at this small example: an implemented PsiElementVisitor with override method visitElement accepts argument PsiElement. This is a time to speak a bit more about what PsiElement is and generally what PSI means.
PSI is the Program Structure Interface, the syntactic and semantic code model that powers many of the platform’s features, especially our review code inspections.
The PsiElement is a primitive in a PSI world; PsiElement is an interface for any other PSI classes, such as PsiFile or PsiComment, from the PsiElementVisitor interface. There are a lot of different PSI elements that have already been implemented, and you should find what you need.
For me, it implemented PSI classes from the IntelliJ Docker plugin to analyze Docker files and commands. I knew where I could find those classes, but if you are struggling with locating the elements you need, you could use an internal PSI viewer. It is worth mentioning that if you are relying on some idea plugin , you should declare this plugin as a dependency. There is a guide that could help you.
Defining your targeted PSI elements is crucial for further creating an inspection. With retrieved PSI elements, you could describe the logic for your inspection and analyze elements.
That’s all for now. If you’re interested in JetBrains IntelliJ plugin development, follow me on LinkedIn to learn about new articles.
