Web Development, 2017 - present

Boords is a powerful tool that helps teams create storyboards and collaborate on their visual storytelling projects. I joined in 2017 as the first employee, and have had a chance to work on a range of features and improvements that have helped the platform evolve.

Besides developing new features for the product, increasing the quality and stability of the existing codebase has also been a constant theme. The most significant upgrades there were introducing Typescript to the codebase (especially challenging in the data layer) and converting from a global-based architecture to modules using Webpack. More about that later.

Frame Editor

When Boords started, the main way of getting images into the application was to create them in other applications (such as Photoshop) and upload them to Boords. Introducing the frame editor was one of the first big features I worked on. It allows users to sketch or build out a scene right in their browser. A lot of the heavy lifting here is done by Fabric.js, but we’ve enhanced it over the years with pressure-sensitive brushes (for people who draw on (pen) tablets), image dropping, stock icons/photos, camera movement overlays, and more.

PDF Export

Another major feature I worked on was in-browser PDF export. This was originally a server-based process happening in our Ruby app, but the library we were using had its drawbacks, and we wanted to do this in the client if possible.

I considered multiple libraries to help us with this and made a couple of prototypes, but eventually found out that none of them are perfect. In the end, jsPDF turned out to work best for our needs, and although it required me to write a lot of boilerplate and do most of the layout code myself, it was very satisfying.

The feature is highly customizable, providing users with the ability to upload custom cover pages and logos, as well as choose text and background colours, fonts, font sizes, and other settings to suit their needs. There are also options to show or hide various elements depending on the user’s preferences.

Initially, we supported a limited amount of PDF layouts and only three frame aspect ratios, so layout dimensions were mostly hand-picked, but nowadays we have about 10 different PDF layouts and 7 different aspect ratios, so I’ve since rewritten the layout engine makes calculations based on the aspect ratio, available width, and the average text length. It comes up with a consistent and aesthetically pleasing result every time.

Frame fields & Shot list view

Over time, we have expanded the number of customizable fields available for each storyboard frame, starting with just three fixed fields and increasing to as many as 20 fields. These fields can be renamed, customized, reordered, disabled, and deleted to suit the specific needs of each project. This has allowed our users to leverage these fields for both creative and logistical aspects of their production process, particularly benefiting our E-Learning customers.

For these use cases, we built an excel-like grid view that makes it easier to manage larger storyboards. It’s a big time-saver for people who work with large storyboards and want easy access to the frame’s status and fields.

Script editor

The script editor was another feature that took a lot of work. We received many requests for a text editor that would allow users to focus completely on the text of a storyboard, so I created one with two main views: a quick colour-coded list of all text in the storyboard and a filtered view where users could see all the content of one frame field for every frame in the storyboard. This made it easy to export content or paste in new content, and it’s been a popular feature with our users.

Modernising and maintaining the codebase

One of the most important challenges over my time at Boords was managing legacy. Over the years, as the JavaScript ecosystem evolved, I managed to make the application evolve with it.

Initially, the codebase used the rails asset pipeline to compile javascript, but it became intensely hard to work with the size of the application. In order to modernize the app, I introduced Webpacker, which uses Webpack and was a huge step forward.

Webpacker and modules

When I joined, modules were not in place, and basically every javascript library or component attached itself to the global scope (window), rather than being explicitly imported or required. Rather than touching all the files in one major rewrite, I wrote a script that scans for these files and imports them explicitly. Over time, as we convert components to proper javascript/typescript modules, this file would shrink. I also wrote code to warn us if these files were not referred to anymore, so they could be removed to save bundle size.

Later, I introduced Typescript to the codebase, which was a very welcome and reassuring addition. I feel more confident making changes, and it makes the data format explicit and visible in your IDE, which is good. One of the big bottlenecks there, however, was our state and data management…


When I joined the company, the codebase was a few years old, and some of the foundational tech decisions made before my time turned out — in the long term — to be unfortunate. One of these decisions turned out to be state and data management library Altjs; it has been basically unmaintained since 2016, doesn’t natively support types, and turned out to be a major bottleneck in various tooling upgrade attempts (ESM, most recently).

Although I have started a foundational rewrite project for Boords in the past (using defacto industry standard Redux), the size of the codebase and the resources available meant that this did not come to fruition.

Recognizing the importance of clear data flow and well-documented types, I undertook the task of making our data layer typesafe. To address this, I wrote helper functions and abstract classes to transform Altjs (which can be a bit indirect and arcane) into a type-safe state management system. For stores that had not yet been converted to TypeScript, I generated automatic type definitions that checked if actions and stores existed, although they did not check the shape of the data. This was a significant improvement and a big win for the project.

Up next

We’re currently working on some major improvements to a core part of the app that has taken months of work to get right. I can’t yet give details about it, but it’s one of the things that will hopefully smooth over one of the parts of the app that feel a bit too technical for some people, and allow people to express themselves in more detail.

Other reading: