Posts by Travis Smith

Code katas offer a method to learn and grow as a developer. But it takes some understanding of the practice to get real value from them.

Earlier this year, we moved comments on to Atlassian Answers, and now we're moving comments from documentation pages on to match. We will provide links and integrations with Atlassian Answers to give you a place to ask questions and get support. Disqus comments on blog posts, such as this post, will remain.

At Atlassian, we have add-ons we develop and use to enable more powerful workflows within our products. Using Atlassian Connect, we can write those add-ons in any language. We often write those add-ons using Node.js. But once in a while we run into a performance problem with an add-on. I had to learn how to profile a Node.js app, so we could live happier lives with less waiting.

If software is eating the world, then JavaScript is eating software, and React is eating JavaScript. In this food chain, it seems React has a big part of our future — which is why I have been spending some time with it. Some interesting things have surfaced...

I exist in a world that uses Python to power some pretty awesome sites and internal tools. From time to time there are REST APIs that I keep on hitting, it would be nice to turn one into a custom slash command for HipChat. I'll walk you through how I did that for an API.

ngrok is a handy tool and service that allows you tunnel requests from the wide open Internet to your local machine when it's behind a NAT or firewall. This is useful in a number of cases, such as when you want to test out an add-on you've been writing for HipChat or a custom webhook endpoint for Bitbucket, but you haven't yet deployed your code to an Internet accessible host or PaaS. The most common usage of ngrok sets up a tunnel to localhost using the random hostname ngrok provides by default, e.g., But that's not all it can do...

Did you know that there's a dialog element in the proposed HTML 5.1 spec? Did you know that you can use this in Blink-based browsers natively or with a dialog polyfill for other browsers? I didn't know this until just recently. Here's what I've learned...

Promises are now here with ES6 in Node/iojs, Chrome, FireFox, and Safari. Easy polyfills exist for the browsers that don't yet support A+ promises. So how would you use them?

You've been working on a Connect add-on using Atlassian Connect Express (ACE). You're to the point where you need to store some data in your add-on. You can use the add-on properties REST API in some cases. You can add an entire storage mechanism to handle this but ACE has a settings storage mechanism already. Get this — you can just piggyback on that! It's not hard to do, and it's perfect for things like global configuration for your add-on.

I got a request from an internal team to get notified when a new post on this blog goes live. It seemed like something one should be able to do without too much effort. So I set aside about an hour to figure something out and now I want to share what I came up with to solve this problem. This same method could be used to integrate almost any services easily, quickly, and without investments in infrastructure.

Atlassian Connect uses JSON Web Token (JWT) for authentication between the host product (e.g. JIRA, Confluence, or HipChat) and your add-on. To ensure the security of everyone's data, Atlassian includes additional claims so a signed request cannot be intercepted and used to perform other actions. We offer frameworks that hide that complexity for node.js, Play!, and ASP.NET as well as atlassian-jwt for those working on other Java stacks. What happens when you don't want to use our frameworks? That's not a problem, you can use whatever framework you want - one of the joys of building add-ons with Atlassian Connect. You can implement the JWT authentication yourself — I'll walk you through the added security features Atlassian uses with Connect.

You may have noticed a new experience for, which includes changes to how our content in Confluence is displayed. This was an interesting challenge for us as we also have static front-end pages around the site that aren't part of Confluence. These pages are the source for the style applied to the Confluence content, so it was important that we had a way to easily share the layout (templates, Javascript, and styling) between the handful of front-end pages at the Confluence content.