A Study in CDEs: Building CodeCanvas with CodeCanvas
JetBrains CodeCanvas is a tool for orchestrating Cloud Development Environments (CDEs). These environments aim to solve some of the long-standing issues of local development setups: tedious onboarding, environment drift, resource-heavy builds, and more. When we started building CodeCanvas, we knew dogfooding would be essential. Our goal was to experience the product the same way users […]

JetBrains CodeCanvas is a tool for orchestrating Cloud Development Environments (CDEs). These environments aim to solve some of the long-standing issues of local development setups: tedious onboarding, environment drift, resource-heavy builds, and more.
When we started building CodeCanvas, we knew dogfooding would be essential. Our goal was to experience the product the same way users would, face real-world issues early, and ensure the platform evolves in step with the needs of modern development teams.
This case study is the result of that process. We used CodeCanvas to build CodeCanvas, and in doing so, we’ve seen firsthand how cloud development environments can transform a team’s development workflow. Here’s what we learned.
CodeCanvas: The technical context
Before we discuss how our development experience has changed with cloud development environments and CodeCanvas, we should touch upon the technical scope of the project we developed: CodeCanvas itself.. CodeCanvas is a complex, resource-intensive system built with a modern, multi-language tech stack:
- Backend: Primarily written in Kotlin, with supporting components in Go
- Frontend: JavaScript
- Build System: Gradle
- Database: PostgreSQL
- Infrastructure: Everything runs in Docker, with development environments launched in Kubernetes (configured via Helm)
- IDE: IntelliJ IDEA
Running this locally isn’t trivial. Because the CDEs mirror real-world deployments, local development requires Kubernetes through tools like Minikube or Kind. While we have helper scripts for bootstrap setup, there is still a lot of OS-specific manual configuration involved, especially when juggling multiple services and dependencies.
It’s also a heavyweight setup in terms of system requirements. Docker-in-Docker alone consumes considerable resources, and to run the full stack smoothly, you’d need:
- At least 64 GB of RAM
- Plenty of disk space (due to the number and size of Docker images)
- A high-end CPU to handle builds, indexing, and service orchestration
In short, even getting started locally required a significant investment of time, hardware, and patience, which didn’t scale well across the team.
How our workflow changed
We started working on CodeCanvas with local development – there was no other choice early on. However, once CodeCanvas reached a usable state, we switched our team to a dedicated instance hosted in Amazon EKS. This instance gets updates as soon as features are implemented, making it our primary development environment and internal testing ground. Later, CodeCanvas became available company-wide, but our team continues to run on the bleeding edge. Here’s how this shift changed our day-to-day work.
Working on tasks and branches
Before (local)
We follow a Git-flow-like approach, and a typical developer works on 3 to 5 tasks per day. Each task lives on a separate branch, and switching between them locally requires checking out the branch, rebuilding the project, and waiting for indexing to complete. This process takes at least 15-20 minutes per switch, as CodeCanvas is a large and complex project. That’s an hour or more of lost time per developer per day just switching contexts. With a team of 10 developers, that equates to over 10 hours lost daily purely on environment management. Multiply that by a month, and the numbers become even harder to ignore.
After (with CDEs)
Now each task or branch lives in its own short-lived cloud development environment. Switching between branches means running a new environment, which takes under five minutes. No rebuilds, no conflicting states. Developers can easily work on 3 to 5 tasks a day without wasting time or mental energy on setup.
Code reviews
In our Git flow-like approach, we never push changes directly to main. Every update goes through a feature branch and is merged only after a code review (more precisely, a merge request review). Each change is reviewed by at least one other team member (usually two).
Before (local)
Reviewers rarely ran the code they were reviewing. It was just too time-consuming to build and configure someone else’s branch locally. Reviews mostly checked diffs in a code-review tool (JetBrains Space) without executing anything. This limited our ability to catch behavioral or integration issues early.
After (with CDEs)
Now, reviewers create a fully functional cloud development environment from any merge request branch with one click. Here they can run the code and test the feature. Because these environments run in separate windows via JetBrains Gateway, reviewers don’t lose context – their main IDE window still holds the task they’re currently working on. This raised the quality of reviews significantly.
Staying up-to-date
Before (local)
Each developer was responsible for keeping their local environment up to date. When dependencies changed or new versions of tools were introduced, every team member had to individually update their setup. This led to inconsistencies, wasted time, and the occasional “works on my machine” issues.
After (with CDEs)
With CodeCanvas, we moved to a centralized approach. A CodeCanvas CDE is based on a template that includes a Docker image with the required tooling and init scripts. To speed up startup times, we use the warm-up feature. It builds IDE indexes and runs a custom script to which we can add any other necessary preparations.
In short, everything that a developer previously had to do manually on their local machine, we now handle centrally via the template and the warm-up script.
But someone still has to maintain this setup, right? That’s where our On Duty rotation comes in. We have a Slack bot that randomly selects one developer each week to be the on-duty person. Their job is to keep the warm-up and init scripts working, update the Docker image(s), and handle team requests related to the setup. This way, a single person maintains the shared environment on behalf of the whole team. We can’t precisely measure the time saved, but it’s significant. On the team scale, it adds up to hours every week.
Onboarding

Before (local)
Getting a new team member up and running was a multi-day effort. They needed to install and configure the correct JDK, Node.js, Docker, PostgreSQL, Kubernetes (via Minikube or Kind), and more. Scripts helped, but much of the setup was OS-dependent and fragile. There was always something that didn’t work out of the box.
After (with CDEs)
Now, we just give them access to CodeCanvas. The environment already includes all necessary tools and configurations, including Kotlin and Go toolchains, the database, dependencies, and IDE plugins. On their very first day, a developer can open a pre-warmed dev environment and start writing code immediately.
Cross-project collaboration
Before (local)
CodeCanvas integrates with other JetBrains projects like the IntelliJ IDEA platform. If someone needed to look into how a feature worked in another codebase or make a small change, they had to go through the same long configuration process for that new project. It was a huge barrier to casual collaboration.
After (with CDEs)
Now, we just run a new environment for the related project. Everything is preconfigured there too. CodeCanvas developers frequently use this to explore or debug features in IDEA without leaving their flow.
The takeaway
If we had to name just one game-changing benefit of using CDEs, it would be the ability to create short-lived, branch-based environments. Being able to run a fresh environment for any task or branch in under a minute and easily discard it when you’re done has completely transformed the way we work. No setup, no cleanup, and no fear of breaking anything – just focused development.
Adoption challenges
Converting a local setup into a CDE template
One of the biggest challenges was converting our local development environment into a working CDE template with proper init and warm-up scripts. This turned out to involve many puzzle pieces that aren’t always obvious when you’re working locally: Docker images with necessary tooling, IDE configuration, IDE plugins, various secrets for accessing project resources (e.g., internal Docker registry, internal plugin server, etc.), and many more.
Maintaining this setup is an ongoing challenge. But we’ve solved that with our rotating On Duty role, which ensures everything stays in sync and up to date.
Remote development support by the IntelliJ platform
Several years ago, when we had just started working on CodeCanvas, remote development support in IntelliJ wasn’t fully mature. Some features didn’t work properly, and a few plugins weren’t yet compatible, making the early stages of dogfooding more difficult. Fortunately, things have improved a lot since then. Remote workflows are now well-supported, and IntelliJ IDEA works smoothly in remote mode.
Why some developers still use local setups
While CodeCanvas has become the default for our team, not everyone has abandoned local development entirely. Some still keep a working copy of the project on their machines, and there are practical reasons:
- Tooling gaps: For example, Helm isn’t preinstalled in dev environments. If someone needs to generate Helm templates, they either install it manually in their environment or do it locally.
- Plugin limitations: Some plugins, like the Go plugin, still have issues in remote development contexts. This makes certain workflows easier to handle locally.
- Missing customization options: Currently, CodeCanvas doesn’t allow developers to configure parts of the environment via code. If someone needs a unique tool or setup, there’s no easy way to add it for just themselves.
- Single-IDE limitation: Right now, a CodeCanvas CDE supports only one IDE at a time. This is inconvenient for frontend developers who would prefer to work in both IntelliJ IDEA and WebStorm (or VS Code) within the same environment.
While some developers mix local and remote workflows, no one on the team uses only local development. However, there are several who use only remote development, which shows how far we’ve come.
Some stats

Here’s what our CodeCanvas usage looks like in numbers, along with some details about the infrastructure powering it:
- ~30 users/month work with the CodeCanvas project. These include both CodeCanvas team members and developers from other teams.
- 16 regular users, including developers, QA engineers, and a technical writer, actively work with the CodeCanvas project every month.
- ~300 development environments/month are created, averaging about 10 environments per user.
- The CDEs we use for the CodeCanvas project have 14 CPUs, 112 GB RAM, and 200 GB disk space – a setup that’s hard to replicate on a typical developer machine.
- It takes 15–20 seconds to start a fully prepared CDE, thanks to our use of a standby pool.
- ~56 developer hours/month are saved by using the warm-up feature, which prebuilds the project and indexes each night.
- ~50% cost savings on AWS storage by storing CDE volumes as snapshots instead of full volumes.
Final thoughts
We started using CodeCanvas because we wanted to dogfood our own product. If we were building something else, we probably would have kept using local environments, just like most developers do today. When you’ve worked in local setups your entire career, you often don’t even realize there’s a problem.
Switching to remote development flipped that perspective. Only then did we realize how many inefficiencies we had just accepted as part of the job, like time lost to configuration, tedious rebuilds, and branch switching. It all became visible the moment we stepped outside that old paradigm.
Using CodeCanvas to build CodeCanvas gave us a real chance to rethink our development experience and build something we genuinely enjoy using. We’re building CodeCanvas to free developers from the pain of local environments, and now we know firsthand just how much of a difference that can make.