Seattle Node and Swift Freelance Developer

I worked on several cool projects this summer, but also had some challenging tests of my skills as a freelancer.

The challenges of being a freelancer

Just a few of them…

  • Scrambling to find new clients when a long-term project ends unexpectedly.
  • Wanting to say yes to a position referred by a friend for fear that offers will stop coming if you say no.
  • Taking a short job to bridge to a longer-term job, then having the longer-term job come through too quickly.
  • Balancing expectations on availability with clients
    • “I’ll be available next month”  doesn’t mean “I’ll start next at the beginning of next month”
    • “I’m available for four weeks”  doesn’t mean “until the end of next month”

As a freelancer, it’s hard to be strict about exactly what work you want to do and can-do. A good goal is to charge enough so that you can say no to all but the best-fit clients.

There’s a fine line between no projects (or too little work) and too much work. In one case I was trying to work while sick to keep the client happy (not that they asked). I didn’t get better, and I barely ended the project on a positive note. It would’ve been much better to just take the time off up front that I needed to not get sick.

Haiku Deck

I worked at Haiku Deck on an awesome product with a fun team for 2 years. Even though I knew funds were tight, it came as a little bit of a surprise to learn that the budget for my time was used up. The ensuing restructuring made for a chaotic week. As a freelancer (unlike salaried employees), I actually like this dynamic change. It’s a challenge to find fresh problems to sole.

The main issue for me, was that I hadn’t been doing a lot of networking. I had gotten lazy about participating in community events. So when my job dried up, I didn’t have another one to jump to. Or, even a clear definition of what I wanted to the next. I did have a lot of side projects I to work on. So I started work on those and tried to get a quick job through Upwork (previously oDesk) to pay the bills.

Scality via Upwork

I’ve always been enticed by the prospect of finding small projects online that are paid hourly. I love the idea of working remote and on my own time. Someday, I’d like to do this while traveling. I had used oDesk as a client before – hiring writers and developers. But I never signed on as developer to get paid for a project.

I applied to about 10 projects. The application process was time-consuming. I tried to write enough and ask enough questions to distinguish myself from the other applicants. I had to explain why I charge 5 times as much as the other developers. I found a good project that was very clearly specified, the unit tests were even provided.

I landed the project and started work – albeit at 2/3rds my normal rate. Unfortunately, the unit tests did not cover a very important and complicated part of the new functionality. So there were a couple very late nights getting things done in a timely fashion for the client. The project was using node to transfer giant files. I wrote up some of my learnings about subclassing node streams.

I expected starting out with Upwork that I would have to discount my rate. What I didn’t account for was that every minute is logged. I don’t mind the invasion of privacy, my assumption is that as I gain trust with my clients – they will pay less attention to my hours. However, I didn’t account for the loss of “soft” billable time. I couldn’t charge for meetings. Every time I went to the bathroom,  took lunch, or researched something, I felt like I needed to clock out. This meant that 40 billable hours required about 50 hours of time. It was intense. Especially when trying to impress the client by meeting the deadline.

Of course, once I did a good job, client offered more work at a higher rate. Which is awesome. It was a great way to discover a new client that I wouldn’t have met through my Seattle network. However, At that point in the summer I wasn’t ready to “drink from the fire hose.”

I’m not sure I will return to Upwork because I think I would be more efficient pitching my skills in person (or on the phone), and finding more interesting projects through my network.

Moment

I wanted to work for Mark Barros because he’s an awesome CEO. But also I wanted to work for him because he pulled me up the half pipe during Tough Mudder. I got to help Moment for a few days with a product launch. Specifically, I worked on an order fulfillment system for cool new phone cases and camera lenses.

The interesting thing about working for moment is that it is primarily hardware company. Turns out that’s not a good fit for me. I’ve mostly worked for companies where software is the main product. For a business like Moment, hardware is the product. They rightfully use whatever software necessary to sell and deliver it. In this case it was WordPress with WooCommerce. A frustrating choice for me as a developer – but a logical one for Moment.

Uberhuman

TA McCann wrote a great blog post about his experience killing this startup right before the seed round. It inspired me to write this post. I thought it would be fun to share my perspective.

With a few extra hours during the summer, I joined TA with a couple other developers and designers at his home. We discussed and coded an initial prototype. My job was writing the Node API to send faxes requesting medical records from doctors. Few providers responded. As it turns out, providers have no incentive (despite the law) to share medical records with their patients.

T.A. and I have a great working relationship. I can show up, ask a few questions, and then implement an experiment. It was worth the investment of free time for the possibility of working together. Sadly, we decided not to pursue it and it’s back to being a side project for me.

Photo app

Another great project that I spent considerable time on over the summer was a viral photo app. It is sort of like a Photo booth with a twist. A friend of a friend and I had a similar idea and the three of us started working on it. As I got the prototype going, we narrowed in on an MVP feature set. A big part of this was negotiating ownership of the project. It will hopefully yet see the light of day.

The project was excellent experience with Swift development. I am impressed by how well documented the iOS APIs are. I was also relieved to be writing code that compiled after lots and lots of JavaScript.

Retirement Calculator and Portfolio Creator

To prove my credentials as an iOS developer, I wanted to get an iOS app in the app store. A close relative is a financial advisor. After seeing his website, I realized it would make a straightforward iOS app. I scoped it out and talked to him. Within about 10 days of work we had Retirement Calculator and Portfolio Creator in the App Store.

I was pleasantly surprised that there was zero pushback from Apple. The release process was smooth. As a marketer, the project reinforced the importance engagement for mobile apps. We have new users that have committed valuable megabytes of their phone. We want to keep them using our app. This is a small insight for me – more obvious in mobile than on the web. Orphaned registered users seem that much closer when your code is in for installed on their phone.

Freeway

The project that I’m most excited to be working on is building tools for freelancers. We’re also matching freelancers to projects. I’m going to skip writing about this now because we’ve got some cool stuff in the works. But I did want to share this call I had with freelancers. We’ve been following up with everybody and I’ll have more on this by the end of the year.

Ookla/Formidable

I worked with Per Nilsson and Anna Luisa West from Formidable Labs at Haiku Deck. They were great. I wanted to work with Formidable again. Formidable offered a great project that I couldn’t refuse, helping Ookla launch a data portal.  You’ve probably used speedtest.net – we helped them report on all that great data. The result was a killer product for their clients.

Related

Top 6 Gotchas with Node.JS

Node.js has many advantages. Many developers know Javascript at least a little bit. Node offers great performance for applications that wait on I/O (like web services). There’s a vibrant open source community creating reusable node modules for almost every task (and a handy package manager to bundle them together). Node is cross platform – the same code runs on Windows, OSX and Linux. And of course, there’s the promise of re-using Javascript patterns on both the client side and the server side.

I love node, but I’ve run into several gotchas with node in production the last few years. Here are the top 6.

1. The website (server process) is fragile. With node, the process restarts on every unhandled exception. This is different from Ruby on Rails, where you have a separate server process like Unicorn, or PHP where it runs as an Apache module.

With one client that was transitioning from PHP to node, our first deployments felt like we were “plugging the dike” – there were so many server crashes. Until we stabilized things, this sort of gave node a bad name (the perception was that PHP was more stable – but in fact the exceptions were just hidden).

Handling all potential errors, as well as unplanned exceptions is impossible. Most deployments have another process to restart the primary node server process when it bombs. If you’re using a PAAS provider, this will be provided for you, but if you want fine grain control of your server (most web application companies will), hosting and scaling (keeping processes up and enough process around) is a challenge.

Common server-restarting libraries for node are: Upstart, Forever, or God.

2. Writing and maintaining asynchronous code. Callbacks are a simple mechanism starting out, but as your server code grows in complexity, they become a hairball. Crazy callback chains (AKA “callback hell”) make code unreadable. Even simple code that could’ve been procedural is forced to use callbacks due to the libraries you’re using.

Mixing synchronous and asynchronous code makes it difficult to handle every error. Furthermore, you have to understand the event loop to know when execution actually switches contexts. As you’re running your code – if you forget to call a callback, you’ll be left waiting to find out what happened. And, asynchronicity makes even your tests become more complicated.

The Async library exists to handle common asynchronous patterns. Personally, I prefer the “promise” (or “deferred”) pattern. It seems like a hack to send a function as a parameter, instead the promise pattern returns an object representing the state of the asynchronous call instead. jQuery has a promise library for the client side. When is the promise library we selected for a recent node-based web site (comprehensive API and more standards based).

3. Too much choice.  The flip side of all those great NPM packages is that there is no clear winning web framework (think Ruby on Rails) for node – in fact, there are several competing server side frameworks (express, hapi, sails, kraken). Each with their own conventions for:

a) File structure
b) Deploying code
c) Building assets
d) Automated testing
e) ORM

And of course, the best choices for each of these changes monthly. This, combined with #2 is why Node is not yet a great choice for simple human facing web sites.

Of course, it’s not necessary to use node on the server.  On one team we used it to great success for building thousands of lines of Javascript and templates to be hosted inside a Python Django website. The problem of too much choice exists for client side frameworks (and build tools) as for the server side (you’ve heard of Backbone, Angular, Ember). Node (with the help of tools like grunt or gulp) is essential to building a modern front-end, just prepared for the evaluation time and conflicting opinions on frameworks.

Screen Shot 2014-12-04 at 10.55.39 AM

Visualization of NPM Packages

 

4. Javascript the language. Many developers think they “know” javascript from having used it in client side code. In fact, they haven’t learned about things like prototypal inheritance, function binding (what is this pointing to?), or variable scoping that are unique to Javascript. Even once you’ve chosen Javascript, there are still a lot of decisions to be hammered out amongst your team. Code conventions (4 spaces or two?) Camelcase or snake case? Jshint is a huge help with this. But, be ready for…

5. Functional versus object oriented programming. There are two very distinct paths any Javascript project can take. Functional style favors dependency injection for testability and clear interfaces (that are theoretically more re-usable). Object oriented favors composition and inheritance for more readable code. The best choice is probably a mixture, as both are silly at the extremes. My current team is finding compromises, but please let me know if you’ve got any guidelines for when to be functional and when to be OO.

6. What about Coffeescript? I hate semicolons. Compared to other languages that give white space meaning (Python and Ruby), Javascript feels heavy and hard to read. I love Coffeescript because it lets you write clear (information dense) code while avoiding common Javascript pitfalls (see #4 above). Node supports Coffeescript natively, but unfortunately, transpiling from Coffeescript means you lose a debugger (and sometimes line numbers).

You also lose the benefit of going with a “lowest common denominator” language (everyone knows Javascript, C, or Java). And, you still need to know javascript deeply (#4). Worse, it can create division on your team. Make sure if you switch to coffeescript, you switch all the way.

Thanks to Scott Nonnenberg, author of thehelp-cluster (a solution to #1) for feedback on this post.

Please leave a comment and tell me: what problems are you having with Node.js?