Innovating Fast with Forge: How we built an app all Atlassians use in two hours

Reading Time: 4 minutes

Each quarter, Atlassian dedicates 24 hours to ShipIt, our internal hackathon. This unique opportunity allows any Atlassian to tackle a feature, bug, or other improvement – anything that makes our products or company better. Last quarter, I teamed up with a content designer and a product designer and set out to build an app for Confluence using Forge. Forge is a popular choice for building apps during hackathons like ShipIt as it allows teams to get up and running quickly, has a tight integration with Atlassian products, and eliminates the heavy lifting when it comes to storage and security.

Our goal was to improve the way Confluence users track changes to a page since their last visit. Read on to discover how we created the Confluence Recent Edits Overview app, the highs and lows of our journey, and how Atlassians have been using the app internally (otherwise known as dogfooding).

Defining the problem

You may already be familiar with the page history functionality built into Confluence, a feature that captures every single version that's ever been published of a Confluence page and allows you to compare these versions side by side. Although it's helpful to have this level of detail available, it becomes difficult and messy when you try to identify exactly what's changed since the last time you viewed the page several weeks ago.

With our new Forge app, we wanted to eliminate the need to comb through multiple versions of Confluence pages by clearly highlighting if there were new edits made since your last visit on the top of the page, and aggregating these new edits for you to view all at once.

The ‘Build’ phase

Given the limited 24-hour window we had for building our app during ShipIt, we knew we needed to work quickly to complete our project. Once we got to work, we were pleasantly surprised with just how simple it was to build Confluence Recent Edits Overview. We started off by talking through the design of the app and what kind of text and icons should display to users. Once we had settled on the overall look and feel, implementation was straightforward and only took us 2 hours to complete.

The solution the team devised required us to save the last version of a page that you visit in Confluence in order to aggregate the changes and compare it with the current version the next time you visit the page.

Why Forge was the right choice for us

Deciding to use Forge turned out to be the perfect choice for us due to its fast time to value, built-in storage (no need to maintain infrastructure yourself), and having lots of ready-to-use tools out of the box. Confluence Recent Edits Overview didn't involve any external database systems (Forge contains basic querying functionality above what's available from key-value storage solutions like Redis or Memcached), and we didn't need to spend time finding where to host data or run scripts because Forge does this heavy lifting for you.

After going through the experience of building this app for ShipIt, it's clear why Forge is the superior option when it comes to building apps for hackathons, where you have limited amount of time to create a solution and want to spend the majority of your time actually building an app and its features vs. setting up infrastructure.

Successes and lessons learned

We're proud to say that our app came in 4th place at ShipIt, and successfully made it to the Marketplace. Getting it ready for the Marketplace included important checkpoints, including speaking with our security team to explain specific details such as how our app will access customer data in Confluence. This was important to consider as app security continues to be top of mind for our customers.

Confluence Recent Edits Overview now helps thousands of Atlassians plus Atlassian customers work more efficiently in Confluence every day. In the words of one Atlassian engineering manager:

Great work! This is already proving to be super useful in day-to-day work

That being said, there are still aspects we would change if we could go back and do it all over again. We decided to go with UI kit at first, and found it did not provide the level of customization we needed. To implement something more advanced, we would have gone with Custom UI, but we realized this when it was too late.

When you switch from UI kit to Custom UI, this warrants a major version update and sometimes requires you to reach out to have admin customers update your app. It takes a couple of days to make the switch from UI kit to Custom UI and the most complicated part is setting up the build and deploy infrastructure. These limitations and benefits are good to know for future apps we build.

Another learning was that when we were building the app, we realized that we could not save more than 10 records per second. When more than 10 people had a page open per second, our app started to fail and was not able to save the version of the page they were on to compare it with the latest version the next time they went to that page. This has been a blocker for many Forge developers and is something that we are happy to announce that we have recently improved!

[Forge storage quotas and API limits] has been a blocker for many Forge developers and is something that we are happy to announce that we have recently improved!

Lastly, Forge storage has both benefits and limitations. Although the Storage API doesn't support all types of advanced queries, for this specific app, I was able to structure the data in a way that was easy for Forge storage to handle. The records in the database represent the latest page version, based on each individual user's view history. So for each user, the record stores the last seen version + the content ID.

Originally, there was only one record for each user mapping contentIdlastSeenVersion. This approach didn't work well because some people read a lot of pages and Forge storage could not accumulate such a massive mapping. Thus, the current approach is to have many keys that look like <userId>_<contentId> and the value is <lastSeenVersion>.

The importance of dogfooding

Dogfooding our own product is essential to truly understand the experience of both Atlassian developers and customers and gain empathy toward our developer audience. This process allowed us to work under a time crunch in a small group to build something simple yet impactful, and identify both areas of improvement and strengths within Forge. We're excited to continue to build more innovative Forge apps in future ShipIt days.

If you haven't already, check out the Confluence Recent Edits Overview app and app code! Do you use the apps you build day-to-day? Let us know on the community!