Timer – From Start to Finish


It has been quite some time since my last Engine Room post and it’s about time I contributed once again!

I am currently the lead developer of our new revamped cross-platform Timer App. Getting the app to the point it is at now was a long and gruesome, but still very enjoyable process. I’m going to roughly outline it in this post.

Getting started

In the middle of January 2014, I had just finished up and released the first version of the Chrome Extension. I had a few options for my next project, but one that caught my attention was a rework of our old Adobe Air-based timer. At the end of the month I had started working on a Chrome app – this was to be our solution for a cross-platform program. However, I was not altogether happy with the idea of restricting our customers to a single browser – although I do love Google Chrome and it’s my browser of choice, it would be unfair to restrict it to Chrome users. We needed a better solution.

Enter NW.js

Around the same time, the Teamwork Chat team, or rather – duo at the time (Adam and Donal) was born. As they were faced with a similar challenge (among many others) of building a cross-platform desktop application, they came up with the idea of using NW.js (node-webkit at the time). Being the new kid on the block, NW.js was getting quite a lot of attention. It wasn’t the only HTML/CSS/JS-to-desktop framework at the time, but it was looking like the most promising. Its having node.js bundled-in was the main selling point, as it opens up a lot more options than client-only JavaScript.

We started off working on a basic app “shell” which could be shared between our projects, however, after initial set-up, our projects went in quite different directions and the base-app repo hasn’t seen any love in quite a long time. Although the Timer codebase hasn’t strayed too far from the original, Teamwork Chat has grown to a big, well-structured codebase – you would not be able to tell it all started from node-webkit-base-app.

The bits we do share in common are prominent in our other projects too, including CoffeeScript which has become a major player in our projects with Knockout.js dominating the interface, LESS for much easier and consistent styling, and Jade for faster templating (although I believe so far the latter is only used in the timer and chat apps).

Once the decision to switch to NW.js was made, the transition was quite smooth – it was only a matter of moving over from Chrome APIs to node.js modules and some minor UI changes.


The development phase of any new project is a lot of fun, but there comes a time when you have to ship the product. Although we previously had Adobe Air-based desktop apps, none of us had gone through the process of releasing an actual standalone desktop app.

Although the process can be quite involved, after a good bit of research we narrowed it down to a simple-enough process for each platform. The most straightforward release were the Linux builds – we zipped the executables and put them up for download – with less than 1% of our customers using Linux, it was not viable to package it for different Linux distros. Deploying for Windows was also quite painless – the only prerequisite was purchasing a signing certificate and the deployment could be described in a few simple steps:

  1. Build your NW.js application
  2. Sign the executable and libraries
  3. Build the installer (we use InnoSetup)
  4. Sign the installer
  5. Upload to the server

Lastly, we had to deploy on Mac. We could have made the process simple and released a DMG or released a standalone installer. However, we decided to go the Mac App Store way as it’s where Mac users expect to find their Apps. We signed up for the Mac developer programme and received the signing certificates. I had hoped that the process would be as simple as signing your files and uploading the app, however it was a lot more complicated…

(Mis)Adventures of deploying to Mac App Store

After the initial submission, the timer app was soon rejected. After changing around some entitlements and removing some unneeded libraries, the app got rejected again. It was time to do more research and, by the looks of it, at that time, there had been not a single node-webkit based app on the Mac App Store. It turned out that as it stood, NW.js had some deprecated and private APIs bundled in as part of Chromium, which were not allowed in the App Store.

The only person at the time making any real progress in getting these APIs removed for the sake of MAS was Trevor Linton and even current solutions are based on his work. Either way, we had to go through a long and gruesome process of downloading and recompiling Chromium’s source with Trevor’s patch applied. Lo and behold, after numerous builds, rebuilds, and entitlement changes, we managed to get accepted into the Mac App Store.

However, ever since release, we had constant reports of the app crashing on launch for some users. After numerous attempts to resolve this with newer NW.js builds and failed attempts at replicating the crash, eventually it was all down to a silly path-length issue. Since the app is sandboxed, it is placed a few directories deep from root, I remembered reading about it just as we started and purposely chose a short bundle identifier to shorten the path length. In the end, we found the bug and resolved it once and for all (hopefully) in the latest 1.2.2 release, however since we updated NW.js version to 0.12.x, we had to change a lot of the internals of the app including changing some bundle identifiers. Again, this version started crashing on launch for users it was working for before – it seems Apple cached the signatures and changing the internals invalidated them, so the sandbox crashed the app. A simple restart fixes the issue, however it was still stressful receiving bug reports – disappointing your customers is never nice. Thankfully this seems to be the end of it!

Lastly, all those who are reading this article and want to give NW.js a go – don’t worry, you won’t have to go through the same process just to be in the Mac App Store. As of NW.js 0.12.3, Mac App Store is now officially supported (albeit in beta), you can find a very comprehensive guide in the NW.js wiki. In fact, this very article was initially going to be a guide, however as johansatge’s guide popped up, I thought it was no longer necessary. And with NW.js now compatible with Mac App Store, we can only expect the same to follow for other similar frameworks, such as Electron.

In conclusion, the timer app was quite a challenging project with a few hiccups along the way. With other projects pending, it may not have received as much love as it deserved, but it feels like the difficult part is over. Now, that we’ve been through the process – future improvements feel a lot less intimidating. Who knows, there might be another overhaul on the way. 😉

Whatever way you look at it – developing cross-platform desktop applications has become much simpler where anyone familiar with basic front-end development technologies can make, build and deploy one. Let me know what you’d build in the comments below or tweet @ripexz!


Keep your projects on track with

Streamline. Connect. Collaborate.

One account works for all apps. Have an account? Sign in here.