Features Tutorials

Workspaces in IntelliJ IDEA

Better late than never! This idiom is probably the best way to describe the functionality we’ll introduce in this article, specifically, support for workspaces in IntelliJ IDEA.

Intro

In a nutshell, a workspace is a meta-project that allows you to manage multiple projects simultaneously. This feature is useful for various reasons, from coordinating complex development environments to having a couple of unrelated projects on your hands

Note for the impatient: There will be some theory and history included below, so if you’re eager to get workspaces into your IDE, just go to the How to use workspaces chapter and crack on! Also, join the upcoming webinar for more details. Please note that this feature is currently in preview, so you may encounter some bugs and limitations

There’s been a ticket for workspace support on our issue tracker since 2011. However, the rise of microservices and monorepositories in the mid-2010s seemed to make workspaces obsolete. The monorepo model was totally aligned with IntelliJ IDEA’s focus on the “one project – multiple modules” approach. Yet, demand for workspaces continued to grow, something confirmed by the increasing number of likes and supportive comments from users on YouTrack. In the next section, we’ll explore why workspaces are still relevant in 2024.

Why monorepos didn’t put an end to the workspace approach 

Monorepos indeed have plenty of advantages over other approaches to code arrangement, namely multi-repos, namely:

  • Better collaboration. All developers are able to see what’s going on in other parts of the project they’re working on. Every change becomes visible as soon as the code is committed. While implementing a service that communicates with another service written by another team, developers can see the other services’ code to get an understanding of how it works.
  • Easier dependency management. In most cases, all projects in a monorepo use the same package management and build tool, making it easier to track dependencies and versions. Also, all application components in a monorepo are usually released together, meaning there is no risk of problems arising with inter-project dependencies. 
  • Cross-project refactoring. Having access to the entire codebase allows the IDE to index code references, meaning it can detect changes and easily perform refactorings correctly.
  • Improved code discoverability. New team members can easily navigate the entire codebase and understand the dependencies between different projects and components.

If you check out a monorepo and open it with IntelliJ IDEA, you’ll see that the monorepo structure fits into the “project-modules” paradigm perfectly. The root folder becomes a “project”, and all subfolders become “modules”. So, on this basis, it looked like the model worked fine, and the implementation of the workspaces feature could be postponed.

However, monorepos have some disadvantages:

  • Monorepos tend to grow quickly. Loading a massive codebase and gathering metadata about the code can be time-consuming. The vast number of commits to all projects within the monorepo can lead to branching, merging, and rebasing operations taking longer than expected. 
  • Restricting access to subfolders might become a challenge. For example, with Git, you can do this by using submodules or provider-specific features like GitHub’s Codeowners.
  • CI/CD integration can be challenging if different projects within a monorepo have different release cycles.

In addition to the purely technical challenges of using monorepos, we can add a behavioral dimension. Usually, developers don’t work on the entire monorepo code. Instead, they tend to focus on an isolated service or a few of them. 

So, despite offering many advantages, usage of the monorepo approach started to wane due to the following:

  • Performance problems: Cloning, pulling, and merging code became challenging as soon as the codebase began to grow.
  • Limited autonomy: In a monorepo, it’s harder to develop and release a selected project independently from other parts of the whole system compared to the multi-repository approach. In addition to this, access control remained a challenge.
  • Unknown boundaries: Projects are treated as a single monolith, so code and abstractions can “leak” into other projects, creating tight coupling. Another consequence is a “broken master”. If just one project within the monorepo is broken, the whole monorepo is treated as broken.
  • Distracted developer’s focus: While developers usually work on a single small project, with monorepos, they have to deal with a codebase of dozens of projects.

The above has contributed to increasing votes on issue IDEA-65293, making it evident that we had to include workspaces as a new feature in our IDEs. 

As a confirmation, surveys show that microservice developers use multiple repositories for development, and this is a growing trend.

Workspaces improve developers’ experience when they work with multiple projects and repositories. Please note that workspaces can also be useful for developers who prefer monorepos. Having the ability to check out particular projects from a big monorepo and work on those only is a great benefit.

If you’d like to dive deeper into this topic, there are some handy articles like “The issue with monorepos” and “Monorepo is a bad idea” that explain things in greater detail.

What is a workspace?

In one of the discussions on the JetBrains support forum, someone posted the following:

Project: This is essentially a description of your final software product.
Workspace doesn’t have anything to do with actual projects and/or software products! It is (ideally) your IntelliJ IDEA’s desktop, merely a container for projects you’re currently working with. This is your current view of your developer’s environment. It does not produce results, but controls how results are produced.

This is the best explanation for the “workspace” concept introduced in this plugin. You can treat a workspace as a collection of the projects that you work on. Every project can use its own technology stack and a build tool and can be run independently.

User scenarios for workspaces

When we made the plugin, we thought about a “typical” setup for an application, comprising:

  • A set of backend services.
  • An API gateway.
  • Client applications, such as a React web app or a mobile app.
  • A collection of custom libraries (for example, Spring Boot starters) used across services.

The code for these components might be organized in a single monorepo or across multiple repositories. Developers might also need to create small “satellite” applications for testing and debugging components like libraries, without the need to commit these auxiliary apps to the main codebase.

It’s important to note that this architectural setup can vary. For instance, in a monolithic application, the backend might be consolidated into a single service, and the API gateway could become optional. In another scenario, if an application lacks a client interface, the focus would be solely on the backend services and the API gateway.

Based on this, we’ve come up with the following major use cases and corresponding workspace configurations for the plugin:

1. Fullstack developer

In many cases, we need to update both front-end and back-end components, which could be stored in different repositories. The workspaces plugin allows us to check out projects from repositories independently, add them to the same workspace, and work with their code as if they were in one project.

2. Microservices developer

Let’s assume that we have dozens of microservices in a monorepo, and we need to update only some of them. There’s no longer any need to import the entire repository into IntelliJ IDEA. We can create a workspace and add only the required services to it. Moreover, we can also use different build tools for different projects. If you build one service with Maven and another with Gradle – no problem!

3. Library developer

This scenario can be used when we need a simple “Hello, World!” application to test a solution. The perfect example of this is the development of a Spring Boot starter. The test application won’t be committed to the code repository, but we may need it to simplify development. In this case, we can create a simple project right in the workspace in addition to the starter project, run the app, debug the starter, and then just discard the app or reuse it in another workspace.

Current implementation

A workspace is a separate folder that stores references to projects from other folders. Additionally, we can create a project inside a workspace folder if needed. A workspace should not be invasive in terms of project settings. IntelliJ IDEA stores project settings, such as code style, SDK, etc., in a separate file in a project-specific folder (.idea). When we add a project to a workspace, IntelliJ IDEA copies its settings to the workspace folder, and then we can change them locally. This means that one project can be included in several workspaces with different settings. The picture below shows how this works. 

Since the functionality of workspaces is still a work in progress, we’ve implemented it as a separate non-bundled plugin to be able to release it faster as we continue to improve it based on the feedback we get from users. We hope that, sooner or later, this feature will become a part of the core IDE functionality.

How to use workspaces

  • Give your workspaces folder a name and add all required projects to it.

You can run projects separately using well-known run configurations in IDEA or Maven/Gradle commands. To run several projects at once, for example, microservices, you’ll probably need a special shell script or Docker compose file. We tried to make the user experience as familiar as possible.

Current version limitations

Let us share some limitations we are aware of. This isn’t a comprehensive list, but it includes key issues that might seem crucial to you and could prevent you from trying the workspaces today. 

  • We do not copy run configurations from the included projects to the workspace. For the time being, you will need to create run configurations manually after project import.
  • There is no constant settings synchronization. For example, if you used JDK 17 in the project and then included it in the workspace – the workspace will use JDK 17. If we upgrade JDK to a newer version in the “main” project settings, the workspace won’t “see” this change.
  • Project renaming is not supported.
  • Resolving dependencies across independent projects is a work in progress.

You can find the full list of issues linked to the YouTrack ticket IDEA-65293

Further plans

We are currently working on the implementation of a number of tasks to make workspaces support even better, notably:

  • Project settings synchronization.
  • Ability to store and share workspace in VCS.
  • More build tools to support.
  • Making workspace a first-class citizen in all IDEs.
  • Simplify run configuration for running multiple projects at once.
  • Smooth debugging across projects.

Feedback welcome! 

The workspaces feature is far from finished. We’ve only just begun our work as we edge another step toward our goal of creating the ideal IDE. We welcome all feedback you might have, it will help us in our efforts! Try out the new workspaces feature, and let us know your thoughts. Your feedback will help us make IntelliJ IDEA even better. You can rate our efforts on the plugin page or add your thoughts and report issues in YouTrack.

5-star us if you like the initiative!

image description