Lessons Learned

It’s been a while since I have posted here, mostly because we are busy building things at Okta. In the past while I have been building our UI framework and generalizing UI components, and thought I should share some high level bullet points of my experience.

1. You are building a framework

Unless you are building a small website, no matter if you’re using backbone, angular, ember, react, vanilla JS or whatever MVC framework the cool kids are using nowadays, in order to have a consistent user experience, without a significant amount of copy/paste boilerplate code, you need to have a solid framework layer. It’s easy to think (as I have) that “we are focusing on building a great product, not a framework” and it couldn’t be more true. However, in order to build a great product, you need a great framework to support you. The investments we made in our framework turned to be a key component in enabling us to move fast, without compromising quality.

2. Abstracting 3rd party widgets is probably a good idea

No matter how stable and mature your 3rd party dependencies are, and how great the developers are, APIs change. By abstracting external dependencies you gain the flexibility of upgrading even a major version, without refactoring a large amount of code. The best way to avoid major refactoring when that happens, (or to get stuck on an older version), is to have your own internal layer of abstraction around it. After all, it’s a know fact that all problems in computer science can be solved by another layer of abstraction except for the problem of too many layers of abstraction.

3. Documentation and code review help spreading the word

It’s really awesome to be generalizing code and writing frameworks around common patterns, but it doesn’t help a lot if the other developers in your org are not aware of it. We’ve found that the combination of code review, and a centric doc site help a lot with training and exposing what features are available. A rotation between developers to help extending the framework is a win win as well: developers get to better know the framework and it’s internals, while the framework gets more contributions.

4. Tests are crucial to success

As any large software application, it would have been impossible to maintain our application without a good amount of tests which validate that:

  • The code does what you think it does
  • Side effects are easier to catch.
  • Future development can be done (in less horror)

Our UIs have proven to be incredibly stable when it comes to regressions, and this is mostly due to our investment in unit tests and end-to-end tests.

5. Cleaning up after generalizing is a good idea

Typically, we decide to generalize a pattern after we are sure we will use it more than once. This way we can assure we are generalizing the right thing, and not what we assume is the right thing. In order to keep the codebase clean and honest, its important to go back to the previous implementations and apply the new pattern. This solves two main problem:

  • It assures that we correctly solved the problem
  • It assures that the next developer running into the same problem will not copy/paste an obsolete/one-off solution

6. You are, by definition, writing tomorrow’s legacy code

It’s impossible follow trends and rewrite your whole application using the new shiny framework that pops up every other week (Heck, The angular 1.x app you wrote last year is considered legacy code today). Instead, we focus on choosing tools that promotes practices we have learned to be useful, with current technology. With the pace the industry is moving forward, future challenges are likely to be along the line of “how to stay current”. There’s no answer to that challenge, but modularity has to be a key component.

If you want to be working with a company which faces these sort of challenges, We are hiring!

Running Jasmine Tests With PhantomJS

Jasmine + PhantomJSI finally got to mess around with PhantomJS and Jasmine, and couldn’t find a resource that gives clear, concise, accurate information, without language specific or build tool specific coupling, so I decided to write it myself.
Fortunately, it is way simpler than I thought.


PhantomJS is a standalone, cross platform command line application which does not require any specific server environment or programming language support.

Continue reading

Keep it Simple, Stupid!

Keep it Simple, Stupid!A while back I wrote a blog post on coupling and the observer pattern. Looking back, I did a pretty poor job describing what it wrong about it. I will attempt to correct this.

We all want simple and descriptive code. Code that is self documented. Code that makes sense, Code that tells us a story. Lets look at a kind of code I have seen many times, in many different variations, using observer based asynchronous javascript code:

var ListView = {
  init: function() {
  onFeedItemsReady: function(items){
    // do something
  // ...

At first, this looks descriptive, and it is, kinda. It’s an object describing the implementation of a publisher it is observing.
That doesn’t sound right. It is telling us about the implementation details and why it is doing things rather than what this object is responsible for and what it is doing. We already know all that!
Continue reading

3 Tips For Writing Better Backbone Views

One of the good things about Backbone.js is it doesn’t tell us how to do things. It leaves it for us to decide what are the best practices for writing views (or any components).
This is also one of the worst things about Backbone. it makes it almost too easy to take the wrong path, and write views that will be hard to maintain.
The principle we should follow when writing a view is to keep it encapsulated, and keep it as “dumb” as possible – a view should know only the bare minimum it needs to know in order to do it’s job, and do bare minimum it has to do.

Here are 3 simple tips that can help us achieve this:
Continue reading

Usability Testing As a Part of Code Review

Code review is one of the most powerful tools we, developers, have in our toolkit.
There are plenty of resources providing information on the value code review can add to any development team.
However, most of the resources I have read, describe how to use code reviews as a tool to find bugs, or architectural issues that are hard to find in an automated way.

It’s also a known argument that code is read much more often than it is written and that it’s harder to read code than to write it, so, our common sense should indicate that writing clear and obvious code can provide a lot of value to our readers, our fellow programmers.
Continue reading

Testing Backbone + RequireJS Applications with Jasmine

In my previous post, I covered the structure of a Backbone.js application using RequireJS.
The next thing (or if you are a TDD fan, the first thing) we do is to run some tests on it.
According to Coda Hale:

Writing tests for your code may not reduce the number of bugs, but it will make fixing the bugs you inevitably find easier.

Obviously, we can take advantage of the AMD architecture, to help us write modular tests (or “specs” in the BDD language).
To get a better sense of the challenges and different approaches in unit testing, I wrote the exact same tests three times using three different testing frameworks: Jasmine, Mocha and QUnit.
Continue reading

Build Backbone Apps Using RequireJS

TodosBackbone gives us a very powerful set of tools. It gives us models, views, and routes – all event driven, consistent and beautifully embrace underscore.js functionality. Being a library rather than a framework, Backbone doesn’t give us application structure. That “glue” we need too initialize the app and glue all the pieces together.
Since coding is by far easier than explaining, I programmed a Todos app in order to demonstrate how this can be done with Asynchronous Module Definition (AMD) using RequireJS.
Continue reading