Working with Junie in legacy code

What Is Junie?

Junie is JetBrains’ new AI-powered coding assistant. It integrates with your IDE and can search, read, and modify the project you are using it in.

This post isn’t meant to cover everything Junie can do — JetBrains already explains that perfectly. What I want to share instead is my experience using it in the real world, especially where it shines and where it still needs work.


My Initial Skepticism

I’ve been skeptical about AI tools in professional settings.

They’re fun for side projects, practical for quick proof-of-concept work, and surprisingly good at writing boilerplate. But I never found them essential in my daily work. They made things a little easier, sure — but not dramatically faster.

That changed last summer.

I started working on a project using Scala and Akka, a stack I wasn't familiar with. The codebase had zero tests and lots of hidden traps. Getting the first test in place was a nightmare. But with a lot of help from ChatGPT, we managed to write a test suite and — finally — gain some control over the code. Things got easier after that.


First Steps with Junie

A few months later, I was invited to the Junie EAP (Early Access Program). I started experimenting with it across different contexts, and it quickly surprised me.

Pet Projects

At first, I tested Junie on pet projects: the UI for a web (I'm terrible with frontend) or my new personal blog. It handled all of them well. Tasks that usually felt tedious — scaffolding, boilerplate, mundane refactoring — became fun.

I had one pet project a bit outdated. As it has a good test suite, I decided to ask Junie to upgrade the outdated libraries. It did pretty well and executed all tests, solved some problems, and made everything work in a few minutes.

I was so impressed that I started sharing my experience with teammates. We collectively started experimenting with Junie in our real projects.

Real Work Projects

At first, we asked Junie to perform simple tasks:

  • Can you update the README for this project?

  • Analyze and clean unnecessary dependencies.

But over time, we escalated. We ask for its help when we are stuck on a problem related to the framework or the programming language. We even tried to ask for implementing trivial parts features, but it changed more code than what we intended, so we discarded this path.

But even when we had to redo parts of what it generated, it still gave us momentum. It helped us move forward faster.


Junie in the World of Legacy Code

A few days ago, Marty Cagan wrote about using AI when working with legacy systems in this article. Whether we like it or not, these systems are a big part of our daily work. Many companies still rely on legacy projects that generate significant revenue, yet everyone seems afraid to touch them. With that in mind, I want to share my personal experience using Junie in one of those legacy systems—probably the most complex project I’ve ever worked on.

The Context

  • Outdated libraries that no one maintains anymore

  • No tests

  • Messy architecture

  • Business-critical, in production, and making money

  • No observability

Cartoon titled "Technical Debt" shows two construction workers discussing why adding a new window takes so long. One building is supported by crutches with a leaking pipe nearby, symbolizing structural issues.

Where Junie Helped

Did I mention that the project doesn’t have any tests? This is one of my biggest red flags on a project, so the first step was to create, at least, some acceptance tests. These kinds of tests allow us to treat the service as a black-box and ensure only inputs and outputs, nothing about the code in between. So, no tests, we needed to add them, but it didn’t seem easy. I asked Junie to create the structure for adding them. It scanned the project and found some very useful internal utility classes I wouldn’t have found quickly. In just three days, we had our first working acceptance test.

In old codebases with no tests is common to find big classes with lots of attributes that are hard to instantiate. This time, with Junie help we were able to generate builders and object mothers that make the task easier.

Furthermore, in this kind of code is not easy to find all the possible requests, and without any documentation, it was a nightmare. Junie was also up for the task!. It identified those endpoints and created a complete collection to call them. Although, it was not perfect some request bodies were not correct, and some endpoints were completely hallucinations.

Where Junie didn’t shine

We tried Junie several times to add unit tests to the codebase, with specific instructions about avoiding create a test double of some class, and the result was not good; all the times it used a workaround to create a mock of the class, even overcomplicating the whole test. That is why I still believe that developers are the best tool to test the code.

It also struggles with doing things in small steps. I provided detailed instructions to follow the TDD flow and stop on every failing test, but it didn’t work, resulting in it making a lot of changes in the whole project for a simple instruction due to a failing test.


Final Thoughts

Junie has quickly become a valuable tool in my development workflow. Especially in complex or unfamiliar codebases, it’s like having an extra pair of hands and a fresh set of eyes — always ready to dig through layers of code, or do the boring stuff so I don’t have to.

It's not perfect, but if you use it with intention and stay involved, Junie can make your life as a developer significantly easier.

JetBrains already announced that Junie will have a free tier to use on their IDEs https://blog.jetbrains.com/blog/2025/04/16/jetbrains-ides-go-ai/, so have a look, try it! I did have some fun in the process.

2
Subscribe to my newsletter

Read articles from Isabel Garrido Cardenas directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Isabel Garrido Cardenas
Isabel Garrido Cardenas

🚀 Senior Software Engineer | Barcelona, Spain 🌍 🛠️After several years of experience developing APIs in high-traffic environments and learning about testing, best practices, architecture, and more with PHP, I changed to Kotlin because the programming language is just a tool that allows us to give value to our users. 🎤 Sharing knowledge is one of my passions. I’ve participated in different online and in-person events talking about testing, also taught about it at university for three years, as well as architecture and best practices. Those are topics that I also share with my teammates. 👩🏻‍💻 After starting with Kotlin, I also create a couple of courses on how to start with Kotlin and develop an API following ports&adapters architecture with Kotlin. 🌟In recent years, I joined Step4ward as a mentor and now as a co-organizer, a community dedicated to helping grow and succeed women in technical careers.