Sever-Side Rendering of Single Page Apps using PhantomJS and Node.js

2014-04-22 by Aaron O'Connell

We present a simple approach to server-side rendering of JavaScript heavy pages using PhantomJS and Node.js. When we receive a request from a bot, we use Nginx to route it to a special Node server. The Node server then spawns a Phantom process to render the page. Once Phantom has rendered the page, Node responds with the fully rendered page.

I recently ran a test to see how well the Googlebot can index a single page app (SPA). It turns out that the Googlebot isn’t all that great. It did a decent job discovering the link structure, but failed to properly read page content. The content of most of the pages that it indexed appeared blank. Having Google index blank pages is really bad, so the rest of this guide is devoted to fixing they underlying cause.

The problem with SPAs is that they often start with a blank page and fill in their content using JavaScript. Since the Googlebot doesn’t have great support for JavaScript, it will often think the initial blank page is what it should index. The Googlebot doesn’t know that it is missing all the content that a normal visitor would see.

Conceptually the fix is easy – don’t rely on the Googlebot to render our pages properly. When the Googlebot request one of our pages, instead of serving up our fancy SPA, we’ll render the equivalent HTML sever-side. We’ll then return this fully rendered webpage to the Googlebot and our site will get indexed properly.

Before we go on, it’s worth noting that Google is totally cool with this procedure. Just make sure to render the same content as normal visitor would see. Don’t try to be clever and add a bunch of keywords that aren’t on your regular site because Google doesn’t take too kindly to cloaking.

You might think that rendering our SPA server-side would be tricky, but it is actually quite straightforward using Phantom. Phantom is a WebKit headless browser, so it can render webpages like Chrome or Safari but has an interface that is accessible from the command line instead of through a GUI. The idea then, is tell Phantom to render our SPA just like a normal browser would, and then pass the fully rendered page back to the Googlebot.

If you don’t have Phantom installed, now would be a good time to install it. Once Phantom is installed, we can run it from the command line like so

Where phantom-server is a script we’ll create and is the URL of the webpage we want to render.


We use system to read in the URL and pass it as the first argument to the web page module’s open method. The second argument to openis a callback that fires when Phantom is finished loading the page. Since the callback is executed when the page is finished rendering, page.content is the fully rendered page we’re after. We then send this fully rendered web page to Phantom’s standard output stream using console.log.

That’s the heart of the beast. All that is left to do is to hook up all the wiring to make it work form request to response. Working from the top down, we’re going to have Nginx match the user agent of the Googlebot (as well as some other popular bots) and send that traffic to a Node server. The Node server will then pass the request to Phantom and wait for Phantom to render the page. Once Phantom is done rendering the page, Node will respond with the the fully rendered page.

First up, Nginx. Modify your Nginx configuration file to include the following:


We’re doing a bit of a hack here to get Nginx to send our traffic to Node instead of where it normally goes (Rails in my case). If Nginx matches the user agent of one of the bots it sends the traffic to error page 419. We’re using error code 419 because it is unused by the specification so it lends itself to this hack. We’ve set up error page 419 to point to @bots which sets some headers and sends the traffic along to our upstream Node server on localhost port 8888.

Next, let’s set up our Node server to respond to traffic on port 8888.


Note: some of the code above is borrowed from Thomas Davis, and I encourage you to check out his tutorial on the same subject.

Here, we’re using Express although we could have also written a simple Node sever to accomplish the same thing. Our implementation is quite simple since we handle all requests with the middleware. First, our middleware reconstructs the requested URL, then spawns a Phantom process to render it. We catch all data that Phantom spits out and store it as content. After Phantom is finished, we take the fully rendered page and ship it out.

That’s all there is to it. We’ve now made the Googlebot happy and that makes us happy. However, there is one gotcha that I came across that I thought I would share with you. I tend to store client-side state in the params of my URLs so that given a URL I can parse the params and reconstruct the intended state of my JavaScript app. This makes it easy to share an URL in an email, for example. However, when I make hrefs inside of anchor tags, I don’t always encode ampersands like I should. This is usually not a problem and everything works fine. However, when rendering pages with Phantom, Phantom is kind enough to properly encode ampersands. In my case, this caused a problem because I had written some client-side code that wasn’t expecting encoded ampersands. This behavior may not present a problem for you but it’s something to watch our for.

I hope you’ve found this guide helpful, and I hope you now have a deeper understanding of what it takes to render your JavaScript heavy pages server-side.

I Coded the Angular Tutorial App in Backbone and it Took 260% More Code

2014-04-16 by Aaron O'Connell

The people at AngularJS created their PhoneCat tutorial app with 48 lines of JavaScript . When we coded the same app using Backbone instead of Angular, we found it took 171 lines of JavaScript – 260% more code. Here, we present a step-by-step tutorial of how we replicated the Angular tutorial in Backbone.

A while ago I decided to check out Angular since everyone’s been talking about it. I went to the Angular website and worked through their fantastic tutorial. I could see the merits of their approach, but I was left with the nagging feeling that if I coded the same application in Backbone it would only take me a few extra lines of code — a binding here and a callback there and I’d be done, right?

It turns out that I was wrong. After actually reproducing the Angular tutorial in Backbone, I found that it took significantly more JavaScript as well as a good bit of finesse. I thought I would share my Backbone version of the Angular tutorial as a step-by-step guide so that it is easy to make a direct comparison between Angular and Backbone.

To get started, clone the backbone-phonecat repository on GitHub into your current directory.

We’re using Node as our back-end so make sure it is installed.

If Node isn’t there, download and install it.

In order to start up the web server that powers this tutorial, cd into the backbone-phonecat directory and run

Node should output Express server listening on port 8888, at which point we can navigate over to localhost:8888, to see a list of phones displayed on the screen.

Screen Shot 2014-04-09 at 4.49.43 PM.png

What’s on the screen presently is the finished product of what we will be building in this tutorial. The tutorial is structured so that we can directly jump to any step along the way by checking out a previous commit using git. In all, there are 11 steps, step-0 through step-10. We’ll begin by resetting our code to step-0, but since we don’t necessarily want to take down our web server by killing the running Node process, it is best to leave the Node process running in the current terminal and open up a new terminal window or tab. Once again cd into the bacbone-phonecat directory.

Step-0 Bootstrapping the Backbone App

To reset our work-space to the first step run

Refresh the page at localhost:8888 and text Nothing here yet! should be the only thing on the screen. Node is currently generating this output by serving up the following file



The text Nothing here yet! appears on the screen because it is the content of our main section. This static text is included on the server side for this step only. All future steps will use Backbone to dynamically generate all page content.

Since we’re just tying to bootstrap the app, Backbone does not have a large role so far. All we’re doing is loading Backbone’s requirements, then Backbone itself. After that we load jst.js, which is an Underscore.js templating dictionary that our Node server will automatically generate for us (which means you should ignore the specifics of the code in that file). The last two scripts are the only real parts of our Backbone app so far.


router.js is a place for us to define Backbone routes in the future. Currently, no URLs will match since the routes object is empty.


init.js creates new instance of the Backbone router and then tells Backbone to start monitoring browser history changes (page navigation).

Step-1 Static Phone List

Reset the work-space to the next step by running

We’ll discuss the more important changes below, and you can see the full diff on github, or by running git diff step-0 step-1

The objective of this section is to use Backbone to fill in the contents of the main section by generating some static HTML . To do this we’re going to need to create a route that will match the root path of our application http://localhost:8888.


Here we match our application’s root path '' to the phonesIndex method of the router that we also defined. The phonesIndex method instantiates a new Backbone view and tells it to place its content inside of <section id='main'>, which by the way, is no longer populated with any placeholder text from the server.

Next, we need a need to create a Backbone view.


All this view does is render the content of a JavaScript template file public/javascripts/templates/phones/index.jst, which we indicate by passing phones/index as the look up key to our JST dictionary.


That’s pretty much it for this section, the only other change was to make sure we told our browser about the newly created JavaScript files. So in views/index.ejs , we added <script src="/javascripts/views/phones/index_view.js"></script>, but that isn’t very interesting and we won’t be mentioning script loading changes again.

Navigating over to localhost:8888 now shows the result of the Backbone generated static HTML.

Screen Shot 2014-04-09 at 6.14.39 PM.png

Step-2 Backbone Models and Collections

Reset the work-space to the next step by running

The full diff can be found on github.

The aim of this section is to use Backbone to dynamically create a list of phones from some source data. To do this we’ll make a Backbone collection of Backbone models, and then pass each of those models to a template to be rendered out as HTML. First let’s create the phone model.


Super simple, but now we can create new instances of Phone and we’ll have access to all the goodness that Backbone provides for models, like being members of Backbone collections and seamless integration into the event bus.

Next up, the Backbone collection to house Phone models


We tell Backbone that our PhonesCollection will be made up of phone models by setting the value of model to Phone. When a new collection is created, Backbone will automatically convert any initialization data to their equivalent representation as Phone models.

We’ll create a new phones collection with some hard coded data in our phones/index_view.js.


this.collection is a Backbone collection of Backbone Phone models, and all we had to do is input the data. We’ve also created an instance of a Backbone view called PhonesIndexListView, which we’ve yet to create. We’ve altered the template of phones/index to only contain a single line <ul class='phones'></ul> so that we have a place for PhonesIndexListView to render its content.

The job of PhonesIndexListView will be to iterate over every phone in the phones collection and render out the corresponding phone template. Let’s create it now.


Currently, on initialization, the view calls its own render method that wipes the HTML of its assigned <ul>. Then it passes each model in the phones collection to renderPhone. The job of renderPhone is to pass each phone model to a new view that will process the model into HTML. That processed HTML will then be accessible throug PhonesIndexListPhoneView‘s el method. That rendered HTML for each model view will then be appended to the phones lists <ul>. The end result is the HTML of all the phones will show up on a list.
PhonesIndexListPhoneView is quite simple since all it does is convert a phone model to its HTML equivalent.


The only interesting bit is that we are passing the phone model to our JavaScript template by referencing it as the argument to the JST template method. The properties (methods) of the phone model are automatically placed in the local scope of the template.


Here we are using the notation [[ for embedded JavaScript, where the inclusion of the equals sign [[= indicates that the the evaluated expression will be interpolated to a string. The Backbone model method get is a convenience method for getting the value of one of the phone’s attributes, and is the complement of the Backbone’s set method (which should almost always be used to set all model attributes so that all model changes will be picked up by event bus).

Details aside, the name and snippet of each phone will now be dynamically written to the screen. We can see this in action by navigating over to localhost:8888.

Screen Shot 2014-04-09 at 7.32.57 PM.png

Step-3 Interactive Search

Reset the work-space to the next step by running

The full diff can be found on github.

We want to add a search field to the page so that we can display only those phones that match the search criteria. To make this happen, we’ll give our phones collection the ability to filter itself in a similar fashion to Angular’s query filter. We can create this new method by customizing the out-of-the-box filter collection method that Backbone (Underscore) provides.


Now when we call call query, on our PhonesCollection we will get back an array of Phone models that match our search term.

Before we go any farther, let’s take a moment to think about the specifics of what we want to happen. We would like there to be an input field on the screen where the user can enter a search term. The list of phones should be updated with each keystroke to reflect the current state of the input field. This means that we are going to need the phones collection to update and render itself every time a user types a character in the input field. There are many techniques that can be used to accomplish this behavior, but the technique we are going to use here is to create a Backbone model called Filter to collect user input.


The advantage of using a Backbone model is that Backbone models emit change events whenever any of their attributes change. This sort of behavior is exactly what we need. If we can link the state of our search input field to the state of Filter, then whenever the input field is changed, our Filter model will emit those change events. We’ll listen to Filter change events and update our collection accordingly. First lets alter the index view to create a new instance of our Filter and its corresponding view

NOTE: vertical ellipses mean that code has been omitted for brevity.

We created a filter instance and passed it down to both a ne PhonesFilterView and PhonesIndexListView. Creating the filter model in this view and passing it to both child views means that each view will have access to filter model events.

First, let’s examine the PhonesFilterView


This view renders out an input tag in its template, but more importantly it uses Backbone’s event hash to set up a mapping between input keydown events and its own setQuery method setQuery looks a little funky but all it does is set the query attribute of our filter model to the current value of the input field. When an attribute of the filter model is set, Backbone will check if the value has changed and if so, it will trigger a 'change:attr' event on the model, where attr is the name of the attribute that was changed. So in our case, whenever the query value of the filter changes, Backbone will trigger 'change:query' on the filter model.

We can utilize this behavior to update our phone collection by listening for those change events.


There is bit going on here, so we’ll take it one step at a time. Toward the end of the initialization method, we set up a listener for filter changes. When a change is detected, the render method is called which filters the collection based on the query. The filtered collection is then set with the models that made it through the query filter. A collection set in Backbone does a smart update of the collection, adding and removing models as necessary. In addition, Backbone triggers an add or a remove event for every model that was added or removed from the collection. In the first part of our initialization, we set up a listener to render any models that are added to the filtered collection. The result is that each model added to the collection appears on the screen (the fancy bit in the render method just ensures that each model appears in the correct order). The only thing left to do is to remove a phone from the screen when it is removed from a collection. This is accomplished in the phone model view.


Here we listen to the phone remove event and use Backbone’s built in View remove method to detach listeners and remove the element from the screen.

Navigating over to localhost:8888 now displays a list of phones that can be filtered with the search field.

Screen Shot 2014-04-09 at 8.55.53 PM.png

Step-4 Phone Ordering

Reset the work-space to the next step by running

The full diff can be found on github.

The idea behind ordering is very similar to text search. We’re going to have an order drop down of possible ordering values. When one is selected, a corresponding Filter sort attribute will be updated to reflect the current state. The Filter will naturally emit a change event, which in this case will be 'change:sort'. We can listen for this event in the phones index list view and re-render the collection. We also want to default the sorting to display the newest phone first. To do that, we default the Filter model, since Backbone supports a default hash out-of-the-box.


Next we alter the filter view to listen for drop down change events and respond accordingly


The template reference here is somewhat interesting because we iterate over an array of drop down values and default the selection to the drop down value where the selected attribute is set to true.


The last step is to have the phones index list view respond to filter changes.


And to actually get the phones to order by age, we have to update our data with an age attribute.


We can now sort to our heart’s content at localhost:8888

Screen Shot 2014-04-09 at 9.38.52 PM.png

Step-5 API integration

Reset the work-space to the next step by running

The full diff can be found on github.

API integration is one area where Backbone really shines. The aim of this section is to issue a request to our web server to fetch our phone model data instead of having it hard coded in the view. Retrieving data in this fashion is commonplace in most production apps. Making this process work is super easy in Backbone. First we need to tell ou PhonesCollection where it can expect to find phones list data.


Next, after we instantiate a new phone collection in the view, we need to tell it to fetch its data from the server.


Finally, since our phones list data isn’t being pre-populated like before, we have to wait until the server responds with the data before we can render it out.


And that’s it. Our phones are now being fetched from our API back-end and displayed at localhost:8888

Step-6 Phone Images and links

Reset the work-space to the next step by running

The full diff can be found on github.

Images and links in Backbone are nothing special, we just need to generate the appropriate HTML using the data already in each phone model.


Here, we are creating the URL of an individual phone by appending it id to the phones path. The approach we usually take is to have our API return an absolute path to the phone show page for us, so all we have to do is display that URL. But, in this case, we are using the data provided by Angular. Same thing goes for the image source.

However, we have one small problem with our links. We have not told Backbone to intercept link click events, so the browser is going to do what it normally does and navigate by doing a full page refresh. Since our app is so simple, we’re just going to intercept and handle the click event where it happens – in our index view.


After we prevent the event from propagating to the browser, we tell the instance of our Backbone router, App, to use pushState to update the browser history and also trigger any appropriate route event that matches the new URL. We have yet to implement any other routes so right now clicking a link will get us nowhere.

On the upside, since we added images and links, our index page at localhost:8888 now looks nice.

Screen Shot 2014-04-10 at 10.55.48 AM.png.

Step-7 Routing the Phone Show View

Reset the work-space to the next step by running

The full diff can be found on github.

We would like to make our phone links work so that clicking a phone on the index page will take you the the correct phone show page. The first step is to create the matching route.


Now, whenever the Backbone router detects that the URL has been changed to match phones/ followed by a specific phone id, it will call the phonesShow method and pass in whatever phone id happens to match. The phoneShow method creates a new PhonesShowView, tells it where it is allowed to render its content, and also creates a new phone model. Specifically, the phone model it creates has one attribute assigned to it, its id. Setting this id is important since it allows Backbone to know where to request information about the phone from the server. To make this magic happen we need to specify the beginning part of the URL that our API responds to.


With the url route specified in the model constructor, calling fetch on any model instance with an id will automatically send a GET request to the url /api/phones/id, where id is the id that we set in the router.

To get the model data fetching process started, we need to set it up in our phones show view.


The first thing we do is tell the model to go fetch its data from the API. Next, we attach a listener to that will call the render method whenever the model data is returned from the server.

As an aside, I guess technically we should attach the listener before calling fetch on the model, but since fetch is done asynchronously, the ordering doesn’t matter since the line that defines the listener will be evaluated before any callback can be fired. End aside.

Once the model is fetched from the server, Backbone automatically parses the response so that the model data can be accessed using the model get method. Just to make sure everything is working correctly, let’s create a super simple template that will display the clicked on phone’s id on the screen.


Now going to the phones index page at localhost:8888 and clicking on the first phone, for example, will display its id.

Screen Shot 2014-04-10 at 11.43.15 AM.png

Step-8 Phone Show View

Reset the work-space to the next step by running

The full diff can be found on github.

In this step, our aim is to have the phone show view display all the phone details on the screen. This step has a lot of stuff going on so it is helpful to first examine what we are trying to make

Screen Shot 2014-04-10 at 11.51.44 AM.png

There are different ways to break apart and render complicated views like this one, but the approach we are going to use here is to break it down into one parent view and three child views.

Screen Shot 2014-04-10 at 11.51.44 AM parent-children.png

The first thing we’ll do is to adjust our main show template to display the name and description that appear in the upper right of the main view and to create HTML elements for the child views.


Next, we’ll create new child views and assign them their elements.


Working down the list, the PhonesShowImageView just initializes and renders


The more interesting question is what is it rendering. The data included with Angular treats images as nothing more than a path to their location on the server. While this is a fine approach, we’re going to promote images from simple strings to full blown Backbone models.


Inspecting further the data that Angular has given us, we notice that one of the Phone‘s attributes is a list of images stored in an array. Since we are going to promote photos to Backbone models, a list of photos calls out to be converted to a Backbone collection. Let’s define that collection.


Since our data modeling is now in good shape, we turn to converting the image URLs to Photo models and converting the images array to a PhotosCollection. The place to do these conversions is wherever the data is being returned to us from the server, which in this case is in the Phone model. Backbone provides to a hook to access the server response as a special model method called parse.


We directly assign a photos collection to the phone model and convert each of the image strings to Photo models with one attribute called path. We also default the Photo model attribute mainImage to be the first Photo model in the collection. We set it using the set writer method so that changes will be automatically picked up by Backbone and the appropriate events will fire.

Finally, getting back to the template of our PhonesShowImageView


The next view in our list is the PhonesShowImagesListView. The idea for this view is to render out a thumbnail for each phone photo. Since we have access to the photo collection through our phone model it’s easy to do using the same technique as we illustrated earlier.


We first make sure the view’s element is empty and then for each of the photos we create a separate photo model view and append the returned HTML to the list. The photo model view currently does nothing more than render the appropriate HTML for its photo model.


with corresponding templatepublic/javascripts/templates/phones/show_images_list_image.jst

The final view in our list is the phone’s specs. This view is really simple.


With a corresponding template that is basically just a dump of the phone’s specs.


In fact, this view is too simple. It doesn’t have a real purpose and probably should just be part of the parent view. The reason we broke it off here was in anticipation of having some nicely formatted details data. We were then going to just loop over the data and programmatically generate all the details, possibly with the use of some string inflector methods. However, the data we’re using from Angular doesn’t lend itself well to that purpose, which is understandable.

Currently our main image view, and image list view suffer from a similar problem of irrelevancy, but we will see the utility of breaking them off in the last section of this tutorial.

First let’s put a little polish on the way our specs look.

Step-9 Phone Show Helper

Reset the work-space to the next step by running

The full diff can be found on github.

The problem that we are trying to solve is that some of our specs return a Boolean so the words true and false are being printed on the screen. We speculate that users would rather see a ✓ to represen true and an ✘ to represent false rather then the words themselves. Making this happen is pretty easy. We first define a global phones helper object and give it a checkmark method.


We used a global object to store phone helper methods, but we could have encapsulated the helper if we wanted to in order to to lessen the possibility of name collisions.

The only other thing to do is to use our new helper in the phone specs template.


And voilà, ✓’s and ✘’s on our page at localhost:8888/phones/motorola-xoom-with-wi-fi

Screen Shot 2014-04-10 at 5.16.01 PM.png

Step-10 Main Image Swapping

Reset the work-space to the next step by running

The full diff can be found on github.

The last order of business is to let the user change out the main image for any thumbnail. We’ll let them swap out the image by clicking on whichever thumbnail image they want to see.

We’re already in good shape since we broke apart our views in step-8 and made our photos full blown Backbone models. The first thing we need to do is trigger an event to let the Phone know which photo it is suppose to replace it’s mainImage with. The natural place to do this is in the photo model view.


This works by triggering a custom event 'imageSelected' on whichever Photo model was clicked, since we linked the click event to selectImage. We also make sure to pass the entire photo model along as data with the 'imageSelected' event. In Backbone, all model events are automatically trigger on their collection as well, so we can listen to the collection instead of trying to listen to every photo model. We’ll do this in the main image view.


Here, we listen for a PhotosCollection 'imageSelected' event and set the main image of the Phone model to be whichever photo model was clicked. Next, the main image is re-rendered since we have a listener monitoring changes to the phone’s main image that calls the view’s render method.

With those additions, clicking a thumbnail photo at localhot:8888/phones/motorola-xoom-with-wi-fi will now replace the main image.

Screen Shot 2014-04-10 at 5.35.34 PM.png


We’ve reach the end of our tutorial. The Angular tutorial contains two more steps – integration with a REST API in step-11 and animations in step-12. We’ve already covered integration with a REST API in step-5 of this tutorial by fetching data through Backbone models and collections. Angular’s animations seem like a great feature, and something that might be fun to do with Backbone, but animations fall outside Backbone’s core area of applicability.

All in all, coding the PhoneCat tutorial in Backbone took 171 lines of JavaScript, whereas the original PhoneCat app coded in Angular only took 48 lines. The extra lines of code in Backbone mostly came from creating a bunch of Backbone views. Backbone requires these extra views because having a well defined view structure greatly facilitates data binding. Angular takes care of most of this behind the scenes with Angular scopes.

I hope you find this tutorial helpful when trying to decide between Angular and Backbone for your next app. Angular seems like a great JavaScript framework and I’m impressed by the brevity of the code. For my next app I’m going to consider using Angular, but I’m really fond of the less restrictive nature of Backbone, so I’ll probably end up sticking with Backbone.

Our homegrown A/B testing framework got us a 251% lift (Part 1)

2014-03-21 by Darren Nix

Six months ago we created a homegrown A/B testing framework wherein we randomize traffic between three servers running different branches of our codebase.  Conversion rate has since increased 251%.

My goal in sharing our results is to encourage you to take bigger risks with your A/B testing. Please treat our particular designs with skepticism; the UX that worked for us probably won’t work for you.  

The original

As a search engine for commercial real estate, our site has only one goal: for visitors to find at least one office space that they like enough to contact.

Version 1

Version 1

So, the simplest measure of our success rate (our conversion rate) is the number of visitors who contact a space divided by the total number of visitors.  A contact is any phone call, email, or web-based tour request.  For the sake of simplicity, the data shown below is only for web-based tour requests from search traffic.

Back in September 2013, our UX was in it’s third iteration since YC Demo Day; it was called Unified View.  The design served us well; it was elegant and power-users liked it because we offered lots of filters and they could choose between photo, list, or map-based search results.

For the month of September, our conversion rate was 0.41%.


How to Structure and Render Views in Backbone

2014-03-17 by Aaron O'Connell

Limited coupling between parent and child views is accomplished by making child views responsible for rendering their own content. Parent views communicate with child views by triggering collection events. Memory leaks are avoided by listening to router events and removing view listeners when appropriate.

The beauty of Backbone is that it gives you lots of freedom. I really appreciate the fact that Backbone strives to find the minimal set of useful primitives instead of deciding everything for you. This is why I was drawn to Backbone in the first place. Backbone solved problems that I actually had without forcing me down a path I didn’t understand. Most of the time Backbone’s lack of rigidity is a breath of fresh air. The downside, of course, is that you have to spend time figuring out how to do things on your own. And since coding client-side JavaScript apps isn’t always the most straightforward thing to do, sometimes a little guidance can be helpful. One area that has tripped me up a bit was how to best structure my views. The aim of this article is to try to clear the air a bit by sharing what has worked well for me.


The Year of Operations Startups

2014-03-14 by Jason Freedman


When we started 42Floors, I didn’t know it was going to be an operations startup.  Naively, I thought it was going to be a commercial real estate marketplace centered around a great product – one of these places where supply and demand come together, one pulling the other and vice versa. Continue…

I want to get into startups, but I don’t know where to start

2014-03-05 by Jason Freedman


I just chatted with this great guy, Alex, out of Boston who wants to get into startups. He graduated from a good college a couple of years ago. He’s bounced around a couple of times in corporately jobs that aren’t the right match and he is ready to take the leap.  He took a couple of classes in computer science, so he’s familiar with code but he’s clearly not an engineer.  He doesn’t have (at least not yet) that founder’s spark that propels him to build something on his own.  Alex wants to join a startup. He just doesn’t know where to start. 


I don’t know.

2014-03-02 by Jason Freedman


I wanted to share an interesting conversation I had with Kiran Divvela back when he was still interviewing.

Kiran runs all of our data supply chain activities. He’s one of those rare types that communicates well, has solid management skills, is fluent technically, and was a perfect startup culture fit.  We knew we had to have him.


Thirty Percent Feedback

2014-02-26 by Jason Freedman


I remember showing school essays to my dad growing up. He’s a really good writer and so getting his feedback before I turned a paper in usually helped me make some improvements.  But whenever I’d watch him reading over the pages, I would secretly be hoping he’d read it and say that everything is perfect.  I obviously thought it was already perfect, otherwise I wouldn’t have shown it to him.

The truth is I didn’t really want any critical feedback.  As a teenager trying to finish his homework, my only goal was to do the minimal amount of effort necessary to get a good grade and be done with it.

It was such a harmful way to think.  And I’ve noticed that I have let it carry into my startup life as well.  Often times, when I seek feedback on a project, it’s not actually constructive feedback that I want; it’s simply approval.  I want a pat on the back and a “job well done.”  Of course, that doesn’t push me to work harder.  It doesn’t provide me new perspectives.  And it certainly doesn’t yield the best product. Continue…

I can rest easy. We’re finally home.

2014-02-18 by Jason Freedman



I wrote this post stream of conscious the night we moved into our new office.  Instead of editing it down into my usual bite-size blog post style, I thought I’d share it as is.  It covers a lot of the emotions and thoughts I had, which I hope will be helpful in some way to you.


We just moved into our new office at 501 Folsom Street.  We’re finally home.

In the end we toured fifty spaces.  That’s right. 5-0.

As a company that makes it easy to search for commercial real estate, I can tell you that finding this office space wasn’t easy.  Of course we had the benefit of knowing our market really well and it was really fun to eat our own proverbial dog food. But it was still hard. Continue…