There is no “I” in coding
Thoughts on teamwork and web development
There is a deep, ingrained perception of programmers as lone rangers. The act of coding appears mysterious to the lay person and it would seem that the programmer is best left alone to conjure up software magic using a black box of tools and their brain power alone.
This is simply not true. More importantly, this mindset must not to taught to the next generation of programmers.
I’ve come to realize over my last 10 years in the digital/web/new media industry that coding (and the act of software creation) must be recognized for what it truly is: an intensively social and collaborative process.
Writing software engages not only developers but also designers, business strategists, copy writers, and marketers at every stage. Most importantly, it’s a continuous conversation with end users and customers.
To be a programmer is not to accept introversion at face value but to embrace being part of a team.
Programming is an intensively social and collaborative process.
At the beginning of this year, a skunkworks team of designers, developers, and strategists came together to help rebuild the website of one of Canada’s largest telcos. The irony of a mobile provider’s website not being properly viewable on the same smartphone they just sold to a customer was not lost on TELUS; they set out to not only relaunch their web properties as a single, fully responsive website, but to also reboot their corporate culture. The TELUS Digital Labs was born.
While I can’t speak to TELUS’ culture pre-Digital Labs, I can say that the word “enterprise” comes up a lot. Their frontend technology stack was in an Enterprise-grade CMS that was not enjoyable to develop in. The technical debt accumulated over the past few years would make it difficult to simply turn it into a responsive website. TELUS had an opportunity here to throw that away and start over without any of the baggage.
As the lead frontend developer of what would become beta.telus.com, I was given a blank slate and the unquestioning support of my teammates and upper management to make the long-term web development decisions required to move the project forward.
This was both exciting and scary. The roadmap was still being built but I knew that one day telus.com and telusmobility.com would be sunset and the safety net of the “beta” label would be taken away. Thirteen million TELUS customers would have their eyes on this project. No pressure, no pressure…
In the end, the beta site is progressing splendidly and has gotten a lot of great feedback. I am proud of the Digital Labs team for what we were able to build in a few shorts months and the process felt very much like starting a brand new company.
And while there were many technical hurdles that needed to be addressed, I think that the complexities that come with dealing with people far exceed technology problems.
Below are some guiding principles to help you, as a developer and as a team member/leader, to successfully approach teamwork. This is based on my work at TELUS and also includes some of my observations while I was Research & Technology Manager at the CFC Media Lab.
- Sit next to your designer(s)
- Always think (and type) out loud
- Automate ALL the things
- There is no room for ego
The complexities that come with dealing with people far exceed technology problems.
1. Sit next to your designer(s)
I don’t know about most developers but I don’t like getting passed Photoshop files at the end of the design cycle and told, “make it look exactly like the mockups”. This is especially irritating when the mockups display features that are not technically possible within the timeframe allocated for a project. Photoshop files are especially not as useful for responsive websites since there is as much to say in between media query breakpoints as there is at set breakpoints.
At TELUS, with almost 30,000 employees, it’s very easy for silos to occur between developers, designers, and marketing teams; waterfall was a common project management style. So one thing that I felt was important to do with the Digital Labs was to make sure developers were involved in the ideation process as early on as possible. As my co-worker Charles likes to say, the role of “user experience” shouldn’t be be the sole responsibility of the person with the title “UX Designer”— it’s everyone’s responsibility to deliver the best user experience.
Design is about solving problems. For developers who don’t often get invited into the creative process or shy away from participating, remember that you are inherently also a problem solver. So you may discover that you can be a valuable asset during the discovery/design phase of a project since you and the designer are both simply trying to do the same thing: solve the problems of customers.
(I will throw in this one disclaimer though: After years of programming, you may be tempted to immediately want to say “no” to features since you will automatically filter out ideas based on their technical feasibility. Keep your cynicism at bay during the very early stages and try to remember that child-like wonder you experienced when you realized that programming was about making ‘something’ out of nothing.)
Collaboration starts with conversations — and the best way to keep the conversation flowing is to keep your teammates as close to you as possible.
Home base of the Digital Labs is a former 600ft² training room at 25 York Street in Toronto. We crammed 30 people in there and it was not uncommon to be sitting elbow-to-elbow. Luckily my designer teammates were really interested in also trying out a very collaborative workflow where developers could start working on lo-fi prototypes based on wireframes well before Photoshop was fired up.
Sitting next to each other (or within chair swivel distance) made it really easy for a UX designer to ask me, “How hard is it to put this element block here in mobile, but then put it here in desktop?”. Or for me to turn to a designer and ask them to try out a rough version of a scroller and give me feedback if it “feels” right.
It is a waste of time and energy to disappear for a week to work on a feature and then have someone tell you that it’s not possible, or that it was not what they were expecting.
The proximity of being close to each other enabled us to have a tight feedback loop where we could share our work early and often.
Collaboration starts with conversations.
2. Always think (and type) out loud
Stop having private conversations and embrace working in the open.
Use public “forums” for long conversations, not email
It’s very common to use email to communicate and send files to other people but email, in the context of collaborating within a large group, has a fatal flaw: the only way for someone not part of the original thread to know what happened in an email is for them to get it as a forward after the fact.
Ideas flow quicker when they are in the open so get those messages out of a private inbox and into a more public forum like Basecamp where you can notify intended individuals of a conversation thread, but it’s optional reading for everyone else. If someone sees a thread in the “Daily Recap” email that Basecamp automatically sends out, they can jump in and offer their 2 cents — sometimes these 2 cents may turn out to be million dollar ideas (figuratively speaking).
Instead of 1-to-1 messaging, use group chat
One major communication issue that we ran into at the Digital Labs was how to best coordinate with the Vancouver office and be inclusive to a few remote workers in Montreal when we were based in Toronto. The 3-hour time zone issue proved to be a bit of a hurdle and distance was a major issue when you didn’t feel the presence of someone.
We tried persistent Google Hangouts to bridge the two main offices but Hangouts is best used when it’s a 1-to-1-to-1 conversation not a many-to-many conversation; and audio was often subpar. We tried an always on teleconference room but it lacked the visual cues that someone was on the other side.
I set up a group Skype chat as a test and invited 10 people to it; this ended up being the winner. Our group chat has been running for over 9 months and we’ve spun off the main room into many smaller group Skype chats for specific teams (with even a dedicated room for deciding on lunch).
Having group instant messaging allows us to be more “public” with our conversations. Important conversations that happen around a table in Toronto could get a quick recap on Skype. Our morning conversations can be read later when the Vancouver office arrives for work in their time zone; and their afternoon conversations can be read by us the next day. If there’s a late night launch, everyone knows how it went as long as the conversation is kept flowing in the group chat.
Document everything; don’t keep tips locked up in your head
Basecamp (or wikis or Google Docs or Evernote) is also a great place for storing working notes or how-to documents.
One of my university professors recommended keeping a daily programmer’s journal since it could act as a log of problems encountered and, hopefully, their solutions. Some of these situations can’t be easily inferred from the final source code so they need to externally documented.
I highly recommend that every time you approach something new, use a digital journal and keep note of all the things that you tried out—whether it’s what file you downloaded, what command you typed into Terminal, or what error you got when you tried a line of code. Keep these notes for your future self that will undoubtely forget how to get a certain API working; you will thank yourself for it later.
But what’s even more valuable is sharing these notes out on an ongoing basis. This is why it’s so easy to appreciate developers who blog — every time you run into a problem, isn’t it magical when you type it into the Google search box and you find someone who has already come across it and has offered a solution?
Whenever I have to train a new employee, I point them to the Basecamp search box and I tell them the keywords to type. This has saved me countless hours of repeating myself, plus I often use the same search box to look up stuff I know I wrote a few months back.
If you ever do training, install a screen capturing software like Screenflow, SnagIt, or join.me pro and record your meetings. At TELUS, we’ve been trying to record both formal and informal training sessions as screencasts. We will then upload the good videos to a private YouTube channel. Again, countless hours saved.
Ideas flow quicker when they are in the open.
3. Automate ALL the things
Let technology do the tedious things that get in the way of getting your work done.
Let Grunt do the grunt work
Grunt is an task runner that runs on top of a local instance of NodeJS. You can write plugins for it using JavaScript and have it automatically run when you save a file.
To ensure that the entire team is using best practices and supporting the browsers we need to, we use Grunt for all sorts of automated scripts. Below are just some examples:
- When you’re working as a team, you don’t want to be the person who has to deal with someone else’s bugs so we use a JSHint Grunt plugin to check our JavaScript files for syntax warnings.
- Webpages perform better with fewer HTTP requests but we write our JavaScript in small individual files to avoid merge conflicts so a concatenation plugin is handy for turning many .js files into a single one.
- Speed up download times with smaller files; when we’re ready to deploy, we use an uglify plugin to minify our JavaScript. (There are also plugins to reduce the size of images.)
- We write our CSS as SASS and use Compass (and a Compass Grunt plugin) to compile and check our CSS for syntax errors.
- Since we need to support IE9 and it’s silly per-file CSS selector limit, we Bless our files using a Grunt plugin that can run shell commands.
- Finally, in order to partially support IE8 and it’s lack of media query support, we run a Ruby script to combine our media queries and then produce desktop-only stylesheets using a Grunt plugin.
Develop without fear with automated testing
Consider adopting a test-driven development (TDD) mindset to make sure that you and your teammates have thought about the code long enough to write a unit or functional test for it. Either you pay the time upfront or the technical debt gets dropped into someone else’s lap later down the road.
An exciting testing tool that we’re trying to implement at TELUS is perceptual difference testing. The core idea around perceptual diff testing is the ability to take a PNG snapshot of your website; the next time you want to deploy, you run another round of screenshots and then compare it to the original set of images. An image diff tool will be able to highlight the changes and you can then focus on addresssing whether that was an expected or an unintended change.
This is going to save our user acceptance testing team a lot of time from having to do manual regression tests. It’s also going to help improve communications between developers since there will be no question around what other sections of the site your code affects. Developers can add new features and refactor without fear.
Brett Slaktin has a must-watch video describing this process as it is used by the Google Consumer Surveys team. He built dpxdt (aka “depicted”) which is a Python app that can compare the state of one server to another. Depicted uses the ability of PhantomJS to run a headless browser to produce PNG screenshots.
Facebook recently released a tool called Huxley that uses Selenium WebDriver to record UI test scripts in-browser and plays them back in order to generate screenshots. These screenshots can then be saved into version control (e.g. Git) and a visual diff tool (like P4Merge) can be incorporated into the workflow for QA review.
More? More!
- If your dev team has a code style guide (or you’re trying to come to consensus on a style guide), install a plugin for your IDE that will auto-format your files on save.
- For projects that need to be spun up more often, I love Yeoman for scaffolding. You can write your own templates for Yeoman and share it with your teammates to help standardize and ease the pain of writing boilerplate code.
- My favourite JavaScript framework is AngularJS since it makes JS code more readable and is very TDD-orientated.
The above examples are only a few ways to automate development from a team workflow standpoint. Add a comment over there (→) if you have more suggestions.
Either you pay the time upfront or the technical debt gets dropped into someone else’s lap later down the road.
4. There is no room for ego
Empower everyone
Support, don’t dictate
We have a perception of leaders as being larger-than-life characters that loudly rally the troops and dole out tasks for his or her followers to blindly execute. While there are scenarios in which such leaders make sense, there is room in the leadership spectrum for different viewpoints of what a leader is.
Shar McBee’s book To Lead is to Serve is given a nod in Daniel Pink’s To Sell is Human (which I recently just finished reading) and it really resonated with how I feel I lead teams.
Some organizations, like Google or Zappos, view management as a support role, not a commanding role. “How can I support you and clear road blocks out of the way so you can get your work done?” are the types of questions this manager will ask their team.
As a developer, you may not be in a management role but you can always ask yourself, “What can I do for my teammates so they can get their work done more efficiently—and with better educated decisions?”
Following on the previous principle of automating everything, keep an eye out for tasks that are tedious or repetitive to do, then build tools for your team to ease the pain. This is especially relevant if you are a more senior developer since most companies that I have worked for have an easy time finding junior devs but are short on senior devs who have that hands on experience to understand the big picture.
Demand that extra time be allocated on a project towards helping each other become more efficient. These tools or learnings will likely be scalable across multiple team members or departments so everyone is able to work smarter.
The real end users of your code are your teammates, not website visitors
At first glance, we write code that turns into a website and then a customer uses this website. We may be tempted to stop there and assume that the customer is the end user of our work but no—the real end users of your code are your teammates.
Your teammates are the ones who will need to navigate around your code to add features. They will need to figure out what you were thinking when you called that variable “foobar” (or even “f”) as they try to track down the root of a bug.
There is a saying, “Write your code like the next person who is going to use it is an axe murderer.” It’s a catchy saying but it is a bit pessimistic and anonymizes who this “next person” really is. So write your code for your teammates.
Use clear variable and method names. Write comments and create documentation. Keep the comments as up to date as the code. Refactor for readability.
Listen
When you don’t see eye to eye with someone, step back and collectively state upfront what goals are trying to be met (or problems being solved). Dig deep into the why before concluding on the what or how. Many disagreements can be settled when everyone can see the same vision.
If a designer (or upper management) gives you a feature that is too complex for the timeframe allocated, take the time out to clearly explain your situation. Turn it into a conversation rather than feeling disgruntled that you have to work overtime.
After an open conversation where both parties are truly listening, the designer/manager might realize that there is a simpler way to solve the problem, or that a rougher proof of concept prototype might suffice to test whether the full idea is worth dedicating more time.
You may even surprise yourself that, after listening to the other person’s side and getting a better understanding of why this feature is important, you’ll be willing to find a way to get it to work because you now believe in it too.
Before this can work, all members in the org chart—whether it be the CEO or the cleaning staff—need to give due respect to each other. Humble yourself by just assuming that everyone around you is smarter than you are; they have different strengths and different points of view so it will never hurt you to be attuned to your teammates.
Organizationally, this might manifest itself as a flatter hierarchy in the org chart with fewer “managers” and more “makers”.
Always ask yourself, “What can I do for my teammates so they can get their work done more efficiently—and with better educated decisions?”
A caveat
After all that, you would think that the engines in the TELUS Digital Labs are well oiled and every day is predictably filled with soft kittens and joy but the truth of the matter is that teamwork is hard work and requires conscious, continuous effort.
Sometimes we slip into old habits. Sometimes it’s easy to forget how change affects more people than just you. Sometimes we’re just busy.
But as a team, it’s our responsibility to be each other’s greatest supporters and most open criticizers. Always keep the dialogue open and keep improving the process.
TL;DR
The sooner we, as an industry and as individual developers, acknowledge the stereotype of the programmer as lone ranger and the unintended reinforcement of the “programmer silo”, the sooner we can start coming together and making better software and websites—as a team.
Teamwork is hard work.
This manifesto originated as a 10-minute lightning talk (of the same title) that was recorded here: http://youtu.be/8lQBsFnaFX4
I am forever grateful for such amazing coworkers from Nascent Digital,Heist, and TELUS for their unquestioning support these past 10 months. And special thanks to my “bosses” from Nascent who, like good managers, always had my back.
I would love to hear your response to this post. Drop a note inline, tweet @PearlChen, or continue the conversation on Google+.