Shane O'Sullivan's technical blog… really ties the room together

Dark Legacy Comics for Android launched!

Posted by Shane O'Sullivan on October 5, 2016

Over the past few months I have been building an app for a friend called Dark Legacy Comics in my spare time.  I previously wrote about the iOS version I released, and now I’m very happy to say that I’ve launched the Android version!

You can get the app from, using any Android device.

As with the iOS version, the app costs $2, and all proceeds go the author of the comic to help with funding his site costs.  Given the comic gets about 200k visitors per month, it’s quite expensive!

On a technical level this is very cool, as I got to reuse about 98% of all the code from the iOS version due to building it with React Native from Facebook.  This allowed me to write the app in JavaScript, but it runs using fast native code on both iOS and Android.  The process wasn’t exactly smooth, as there are still a lot of differences between the platforms that have not been papered over by the framework (some of which I describe here), but in general it’s far, far more efficient than learning both Objective-C and Android development.  So, thanks to my colleagues at Facebook for building such great tools!





Posted in Technical | Leave a Comment »

Troubleshooting setting up a React Native Android dev environment

Posted by Shane O'Sullivan on September 9, 2016

React Native is awesome, but the docs leave something to be desired, particularly for Android (the RN team is working on it!).  I recently wanted to get started on building an Android version of the completed iOS app I previously shipped using React Native, but it turned out to be an overly painful process.  The docs assume knowledge of Android development, which I do not have, so here are the steps I used to get up and running on my Mac.

My setup

  • React Native version 0.32
  • Mac OSX 10.11.6 (15G1004)
  • javac version 1.8.0_011


  1. Follow the instructions for installation in Dependencies for Mac & Android.
  2. Open Android Studio from Applications, step through the setup wizard to download all the packages it needs (about 250MB)
  3. To run the emulator, you need to create a Virtual Device
    – Use AVD Manager to create a virtual device (   I chose to use a Nexus 5X emulator for no other reason as it was the default selected one.Screen Shot 2016-09-08 at 10.04.40 PM.pngScreen Shot 2016-09-08 at 10.05.50 PM.png
    – Run that device by clicking on the green Play button
  4. In your terminal, change directory to the root of your React Native app, and run
    react-native run-android

If at this point your React Native app shows up in your emulator, congrats, you’re now a React Native Android developer!

If not, read on.


You might see this error:
Could not run adb reverse: spawnSync

If so, add the following to ~/.bash_profile if not already there:
export ANDROID_HOME=~/Library/Android/sdk
then run
source ~/.bash_profile
and run
react-native run-android
from the root of your app again. (From Stack Overflow:

If you get the error
failed to find target with hash string ‘android-23’
try deleting the folder
and running the command again (from  This apparently worked for some people, but not me.

You should install:

  •  “SDK Platform” for android-23
    • Go to Tools/Android/SDK Manager
    • Click the “SDK Platforms” tab, if not already selected
    • Check the box for Android 6.0, which is API version 23

Screen Shot 2016-09-08 at 9.28.01 PM.png

  • Android SDK Build tools for version 23 (I installed 3 of them, see screenshot)
    • Go to Tools/Android/SDK Manager
    • Click the SDK Tools tab
    • Check the “Show Package Details” box in the bottom right
    • Under “Android SDK Build Tools” check all boxes for anything with version 23.

Screen Shot 2016-09-08 at 8.21.11 PM.png

This got me past this error.

I then got the errors:
<project folder>/android/app/src/main/java/com/dlc/ error: method does not override or implement a method from a supertype


<project folder>/android/app/src/main/java/com/dlc/ error: constructor FBSDKPackage in class FBSDKPackage cannot be applied to given types;
            new FBSDKPackage()
  required: CallbackManager
  found: no arguments
  reason: actual and formal argument lists differ in length

It turns out I had generated my project on an earlier version of React Native, as I was working on the iOS version first, and the Android code it generated was no longer compatible with React Native v0.32.  To fix this:

  • Create a temporary folder
    • mkdir ~/tempFolder
    • cd ~/tempFolder
  • Now create a new React Native application with the exact same name as your application in that folder.  This is important as the React Native tools embed that in a number of files that they generate.
    • react-native init MyAppName
    • Rename the folder in your original app “/android/app” to something else, e.g. “/android/app_old_and_busted”
    • Copy the folder ~/tempFolder/MyAppName/android/app to the “android” folder in your app.
    • run the command “react-native run-android” from the root of your app again.
  • Woohoo, it worked for me!

Posted in Javascript, React Native, ReactJS, Technical | 2 Comments »

Dark Legacy Comics, my first React Native app

Posted by Shane O'Sullivan on May 30, 2016

I’ve been a fan of the React Native framework for a while, even ignoring the fact it’s built by my colleagues at Facebook.  However since I spend my work days talking to engineers rather than coding these days, I haven’t had a chance to build anything real with it.  While I had some time off recently I fixed that, and built a fun new app for a friend, Dark Legacy Comics, now available on the Apple App Store.

It was a fun process, getting to build an app that runs really fast and smooth using all native UI components on iOS, but writing 99% JavaScript.  Given that I neither know Objective-C nor have the time (nor inclination) to learn it, it’s pretty amazing that I can now write an app that works this well.

The process was nowhere as smooth as it needs to be, given I ran into many tricky roadblocks with upgrading versions, importing 3rd party libraries, weird iOS build errors and more.  Still, with a little perseverance and quite a bit of cursing, I got it all working.  So, try it out (sorry it’s not free, all proceeds to the author of the comic, but he’s awesome and more than deserves it after 10 years of hard work) and let me know what you think!

Posted in Technical | 2 Comments »

Mobile Tesla Motors forum

Posted by Shane O'Sullivan on November 24, 2014

I like to keep up with discussions about the Tesla Model S in their online forum, but this is very difficult to do on a mobile device, since it it not optimized for that, and still focuses on a desktop layout.

So I fixed it!  Behold the mobile Telsa Motors forum – .

Open this on a mobile device and enjoy browsing through all the comment threads.

Since I do not work for Tesla and don’t have access to their forum code there are some limitations:

  • It’s read only.  If you want to comment you have to go to their site.
  • It can’t show private posts, so only public posts are visible
  • To save on server costs, it refreshes every 10 minutes, so sometimes may not be as up to date as the real forum.  This should be mostly fine though


Posted in Technical | Leave a Comment »

URL & JSON Decoder in ReactJS

Posted by Shane O'Sullivan on July 20, 2014

I was debugging some network traffic, and needed to decode a URL that contained JSON values.  It looked like there was no good example readily discoverable on Google, so I threw together one using ReactJS, the amazing JavaScript library from my colleagues at Facebook.

Check it out at

It’s a simple single page application, and can be used as a good example of how to structure a simple ReactJS application. The source code is available on GitHub at .

Screen Shot 2014-07-19 at 6.21.10 PM

Posted in Technical | Tagged: , , | Leave a Comment »

Tesla Forum Search

Posted by Shane O'Sullivan on August 22, 2013

Tesla Forum Search

I like to read the forums on the site, but a big problem they have is that there is no search feature.

To solve this problem, I wrote a Chrome plugin to do the searching for you.  It basically crawls the forums, tokenizes the posts and builds a simple search index.  This is stored on your computers hard drive, which makes searches very quick.

Try it out!

Posted in Technical | Tagged: , , , | Leave a Comment »

Launching Ads Reporting at Facebook

Posted by Shane O'Sullivan on June 26, 2013

For many months I and a few other engineers at Facebook have been building a new reporting tool for advertisers. This involved both a huge amount of work to build a fast, flexible backend that lets you slice your data in almost any way you can think of, in real time, and a UI to match.

I’m really proud of this work, which involved building a DataTable that can handle an infinite number of rows and columns, in place column reordering, resizing and all the other fun stuff that goes along with it.

If you run ads on Facebook, give it a try. It provides an unprecedented level of detail on the performance of your campaigns including how much you’re paying for the actions that you care about, such as mobile app installs, page likes etc.

Some press about it:

FB Studio (with video):




Posted in Technical | Tagged: , , , | Leave a Comment »

Edgeconf 2013 Web Performance Panel

Posted by Shane O'Sullivan on February 12, 2013

Edgeconf 2012 Web Performance Panel

I had a great time at Edgeconf, taking part in the Web Performance panel. We got to discuss many of the common issues that web developers face when building complex web apps, such as avoiding reflow, repaints and avoiding garbage collection.

The full video is available now HERE.

The slides are available here

All other panel videos are available HERE, or will be soon if not yet uploaded.

Posted in Technical | Tagged: , | Leave a Comment »

Click, change then animate: My self imposed rule for a fast & smooth UI

Posted by Shane O'Sullivan on October 14, 2012

A few months ago I joined the Ads Interfaces team at Facebook, after almost two years on the mobile team, and am very proud of being part of the group that shipped a full rewrite of the Ads Create Flow ( last week.  The application is highly complex, with many varying user interface elements, lots of data floating around, validations and so forth, so it made sense to write it 100% client side in JavaScript. 

In many ways it’s a standard MVC application with

  • declarative view definitions, so you can easily relate the code to what you see in the Web Inspector
  • well defined data models which can be observed for changes
  • bidirectional bindings between views and models to keep the UI in sync with the data.  That is, if a piece of data changes, the UI should just update itself.  Of course, it is also possible to add code in between any binding if some more complex processing is needed.  For example, when changing the top level objective (clicking one of the huge buttons), I wanted it to animate the change, so rather the transference of the data update is delayed.

My New Rule

One of the primary lessons I took away from this is that asynchronous data fetching is one of the leading causes of users feeling like a UI is “webby”.  That feeling where the interface suddenly, with a jerk, jumps around and changes size.

This is often caused by images loading, or by an API call returning, resulting in the UI being redrawn.

I decided on a new rule to apply to interfaces I work on:

The UI can change suddenly when the user interacts with it.  All other changes should be smooth.

What this means is if the user clicks a link or a button, it’s OK to immediately change the UI, since they can see the causation.  However if new data comes back, or a large image loads shifting the entire UI up or down, this should be smoothly animated. 

I’ve found that this both gives an interface a more polished feel, but also draws the users eye to important information.  In addition, if they were already reading something, trying to make a choice of what to click next, if that jumps even a couple of centimeters they have to start searching for it again – it may have gone below the bottom of the screen.  However if it smoothly moves there over 300ms, they continue without much interruption.

It’s important to not go overboard with this of course.  Don’t animate everything, as it’ll feel gratuitous.  I’ve found that sticking to animating only asynchronous operations leads to an application feeling both fast and professional.


Some examples in the Ads Create Flow are the large image that loads for Sponsored Stories (the bottom picture), and the entire Ad preview that loads as a result of a data callback (under Right Hand Column Preview).


One caveat is that on IE 8 & 9, you’re going to have a bad time.  I chose to not bother with janky timer based animation solutions, both in the interest of saving time, and from a healthy disdain for legacy browsers.  So, I advise to stick with CSS3 animations, and let the users of old browsers have a working but less attractive application. 

Posted in Facebook, HTML5, Internet Explorer, Javascript, Technical | 4 Comments »

What Git branch was I working on again?

Posted by Shane O'Sullivan on June 16, 2012

A situation I often find myself is remembering what Git branch I was working a few hours ago.  Partially this is my own fault, since I tend to name Git branches after task IDs, e.g. “12345”, in order to easily find them, but also just my brain has limited space and can’t remember more than three things at any one time.

A useful command I’ve found (for the Mac and probably Linux) is the following

for k in `git branch|perl -pe s/^..//`;do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k|head -n 1`\\t$k;done|sort -r

This prints out a list of your branches, and the length of time since you last checked them out.  It makes it really easy to find that unmemorable branch.

Of course, it’s easier if you put that command in a reusable function, e.g.

function listGitBranchesByMod() {
    for k in `git branch|perl -pe s/^..//`;do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k|head -n 1`\\t$k;done|sort -r

inside some *.sh file on your PATH.

I found this somewhere on the web, and cannot find it again. If it was you, please let me know so I can link to the original. Oh, and thanks!

Posted in Technical | Tagged: , | Leave a Comment »

%d bloggers like this: