Last week was Tighten's annual company on-site, where we bring the entire company together in one place for a few days to get to know each other, make plans for the future, and accomplish a few high-level tasks that are easier in person--for example, designing the next year's T-shirt.
Samantha Geitz and Keith Damiani had already discussed coding a set of identical features in React and Vue on a 20% day, and after a bit of smack talk, they decided to rumble on "hard mode" and livestream the whole thing.
We built a site at http://battle.tighten.co/ that made it easy to chat, watch the Twitch stream, and even vote for your favorite framework. Around 30 minutes before the scheduled start time, the Tighten team gathered in Dan's office with pizza to get set up.
Keith and Samantha had already set up a basic Laravel skeleton app, and they now set at a desk with their "team" around them--other Tighten developers who were ready to pull questions and comments out of the Twitch chat, look up confusing syntax in the documentation and Stack Overflow, and just generally be useful and provide moral support.
We originally considered sending out two Twitch streams, one from each side. We're still hoping to set up a system that makes that possible. But what we really wanted was the ability for a single host (me) to flip back and forth and give color commentary, so I called both developers with Google Hangouts and shared the Hangouts window from my screen. The pro: I was able to keep things engaging and interesting, flipping back and forth between the developers and the spec. The con: it was hard to mix the audio well and you never could see what the OTHER person was doing.
We have some ideas about technical setups we can use next time to get around some of these issues, but even with those concerns, we had hundreds of viewers who gave glowing feedback, so it seems it didn't get in the way too badly.
The challenge was straightforward: build a fake Twitter client, consuming a simplified Twitter-style API that I created and put online before the battle, that could show a list of all tweets and a compose tweet window. You can see the whole spec and the optional "bonus" tasks here.
In the end, I chose the winner based on three criteria: first, whether they accomplished the entirety of the challenge; second, how elegant and simple their code seemed; and third, how many people voted for each framework as their favorite framework.
Both devs completed the basic app and no bonuses, and there was unsurprisingly (in the Laravel community) a huge pro-Vue voting block. Vue had a small lead because of the votes, but I waited until the battle was over to evaluate the elegance of each solution.
Having used both Vue and React before, I have no doubt that both are powerful frameworks that, at times, feel like the absolutely perfect tool for a project. I was most curious, then, to see how they both fared on a very simple and very common set of tasks: connect to an API, list a resource, and allow for creating a new resource.
My final vote? Vue won the day. For apps as simple as this, Vue just doesn't require as much complexity or filler code. In my humble opinion, React shines more and more the bigger and more complex the codebase, but at the simplest stages it can often feel a bit clumsy, and that definitely played out in this battle a little. Both apps were great, and I'd be perfectly happy working with either, but Vue just felt a little bit simpler and cleaner.
Both Samantha and Keith continued work on the challenge after the livestreamed portion was over, cleaning up their code and completing a handful of the bonus tasks. You can find the React repository here and the Vue one here.
So how did it feel to be on the front lines? I'll let Keith and Samantha tell you in their own words:
What was it like participating in a developer battle in front of an audience?
Keith: Pretty damn terrifying, actually. This was really my first attempt at coding in front of any group larger than one or two people, and I learned very quickly during the dev battle that live coding of this nature is not something that comes particularly natural to me. It was a ton of fun and a huge adrenaline rush, but all that adrenaline (ok, and maybe the beer and Red Vines) seemed to shut down my focus, rather than heighten it. What that means, for me, is that I’m going to seek out opportunities to practice wherever I can—through screencasting, Twitch streaming, presenting at a user group, etc.—to help develop my ability to code more confidently under pressure. And, so that I can beat you handily when we stage our rematch.
I definitely ended up with a renewed respect for those rock stars who regularly live code online or at conferences.
Samantha: Live coding is *hard*, y’all. I’ve spent hundreds of hours writing React apps over the last year or so, and I was still making all sorts of stupid mistakes. “OH MY GOD, WHY ISN’T THIS SHOWING UP? Oh, derp, I forgot to import it.” Not to mention that fat-arrow function syntax that tripped me up not once but twice. I refuse to watch the video stream in its entirety because I know I’m going to cringe the whole time.
Looking back, though, I’m so glad I went out of my comfort zone and did it. I definitely had to leave my ego at the door for something like this, but it ended up being a lot of fun and a great team bonding experience for Tighten.
What do you wish you had done differently?
Keith: Getting more than 3 hours of sleep the night before probably would have been a solid idea.
But besides that, I should have spent the first five minutes of the battle drawing up a roadmap for the app. I’m a pretty visual thinker, and I typically attack any problem by first drawing a mockup or schematic of whatever I’m going to build. That process helps me sort out structure and relationships, helps me see the big picture and the small details all at once, and gives me a moment to consider potential stumbling blocks I might encounter along the way. It also provides me with a visual point of reference as I move through my code, so that my next step is always clear. During the dev battle, I found myself flailing around, constantly thinking about what was coming next at the expense of thinking clearly about what I was working on at the present moment, because I hadn’t built that visual roadmap up front.
I also made several mistakes that stemmed from trying to reuse bits of code that I had already built into the base app, or from snippets I had lying around from other projects, rather than just building everything from scratch. It’s so easy to overlook the details of some code when you just pull it in from somewhere and modify it, and in a couple instances where I had brought in a snippet to try to save time, I ended up losing more time fixing mistakes than I saved. The act of writing each line out piece by piece is very clarifying, and in this circumstance, would have been a safer way to go.
Samantha: My biggest regret is pulling in the immutable helpers library. I end up relying on it in a lot of my projects where I’m doing complicated things to state, but for something this easy, I should have just used a spread operator and called it a day (and have since updated my code accordingly.) I also should have abandoned ship on it as soon as I was having trouble getting
push to work, but I ended up getting tunnel vision and burned a lot of time I didn’t need to.
I also shouldn’t have tried to create a modal in the last few minutes. It was a huge risk, and when I couldn’t get it to work, I almost ended up with a totally broken project to demo at the end.
Ultimately, though, I'm pretty happy with how I did. I definitely need to practice coding in front of people under pressure--it's a skill totally separate from writing code by yourself in your living room or even pair programming--but for my first time live coding, I managed to get a lot done in under an hour.
This was just our first battle. It's definitely not the last. Next time we'll have another challenge, and next time I'll have a better handle on how to set up the stream and mix the audio.
We may even try a battle when we're not all in the same place, just to up the technical complexity.
Finally, the stream! I've edited in an intro and edited out a bit of my blabbing, but this is essentially the same stream that went on Twitch. Take a look and let us know what you think!