Dan and Matt met by chance encounter at a coworking space in Chicago in 2011. We’d both worked for years in organizations where developers lacked meaningful support and arbitrary deadlines were set by someone else, often without our input. We felt trapped in a cycle where the only way to meet expectations was to work endlessly, which left us burnt out and on the brink of leaving the profession. But a few intense conversations rekindled our passion for the actual craft of software development, and surfaced a shared belief that ran counter to what we had experienced: businesses should exist to serve people.
We imagined that there might be a better way to run a company, where the primary purpose was to provide a space for people to care for one another, and the actual work output was a crucial but secondary purpose. So we set out to create the company we would want to work for.
The question that remained was whether a company like this could actually turn a profit. But if our stated purpose was to help people live better lives, and we are very good at our jobs, lots of great and talented people should want to work with us. So we should be successful, right?
We ran the experiment for a few years, picking up lots of ideas along the way, and generally seeing what we could get away with. Bit by bit, we dropped the parts we hated and replaced them with ones that we liked. We stopped estimating time, and started giving and expecting trust. We stopped tracking individual hours and started putting in a good day’s work. We stopped agreeing to high-stakes deadlines. We scrapped the dumb parts of Agile and focused on agility itself. We stopped working overtime.
We discovered that rather than producing average results in a feel-good context, the experiment produced exceptional results. Building structures around caring for people actually correlated with financial and reputational success. We weren’t shocked that it worked, but we were shocked that it worked this well. Looking back, it shouldn’t have been such a surprise. People like feeling supported and appreciated. They hate being treated like “resources” or fungible units of labor.
Importantly, caring for someone doesn’t mean just saying nice things — it also means having the hard conversations, those which are most beneficial to their growth. It turns out that when every person is heard and supported, our values and practices align and we make incredible shit.
We’ve come to believe that a people-focused team full of healthy, growing individuals who communicate and empathize well with each other produces better results than anyone else.
This realization is only the beginning. Implementing it has been hard at times, but it’s mostly been a really fun adventure with a bunch of the most fabulous people we’ve ever met. What follows is meant to be fun too. It’s the advice we wish we someone had given us. It’s a manifesto, so we won’t mince words. Take the parts that interest you, with a healthy pinch of salt, and leave the rest.
Hiring well is hard. But it’s impossible to make a great company without terrific people. Hire people you actually want to spend time with. A strong team can overcome a bad project or two, but a bad hire might be fatal to that same team.
Put time and energy into building a hiring process that places value not just on technical ability, but also on things like:
You can teach programming (or design, or project management, or just about any other skill), but you can’t teach someone how to be good and decent. Look for people who aren’t afraid to express a strong preference, or admit to having failed at something in the past, or ask a question that might make them look foolish. In particular, never, ever hire people who are stubbornly preoccupied with proving their own competence.
Build a pipeline of potential hires long before you need them. Be constantly talking to people you find intriguing or different, in person and on the internet, and cultivate professional friendships with them. Look outside your friend and affinity and comfort circles for these folks. When you encounter a great person who isn’t yet qualified for a certain position, consider hiring them as an apprentice, and help them round out their skills on the job, or offer a mentorship to help them get apprentice-ready.
Before you hire people, create a space where they can thrive. After you hire those people, continuously cultivate and prune your environment and policies to better serve the team you have and the team you hope to have. Getting these amazing people in the door is only half the battle; giving them an incredible experience is the other.
Every big decision should be made with your team’s security, growth, family life, physical and mental health, and stress level in mind. Each of these aspects of life is under assault by the fetish of hustle culture, particularly in the U.S. Be the antidote to this. Doing right by your team yields the best results, and helps tremendously with employee retention, but that’s not why you should do it. You should do it because it’s the right thing to do.
Employees’ outside interests are the raw material of company culture. Fill your team with people who have all sorts of wild and diverse extracurricular interests, and give them opportunities to share their passions on company time. Team building exercises are dull with people who never do anything but work, but can be super engaging with a whole crew of fabulous weirdos willing to nerd out about things you’ve never even heard of, or breathe new life to something you thought was boring by going super deep.
Once you have a team on board, the culture belongs to them. Lead with values and policies at a high level, and in individual interactions at a low level, but let the culture itself develop organically. Nobody likes hackneyed corporate mumbo jumbo or corny rah-rah crap. When they have ideas for how to make things quirky and fun, just participate. Don’t be too heavy-handed at the tiller.
Great people tend to stick around in engaging, dynamic environments, and bail quickly from banal, life-sucking ones with no clear purpose. Talk to and listen to your team, as people, then try to create a place that these people, in particular, will find energizing.
The Agile Industrial Complex, as Matt often refers to it, has convinced the programming world that agility means adopting a certain set of dogmatic practices that use words like “standup” and “Scrum Master” and “velocity.” There is nothing wrong per se with these practices and systems, and they can be valuable when used appropriately. But they aren’t required for great work to get done.
When we talk about agility, we mean exactly what a non-programmer would expect us to mean: being light on your feet and able to change directions on a dime. Athletes are agile. They adapt fluidly, in real-time, to dynamic situations, using fundamentals to guide their moment-to-moment decisions.
Be agile. Find the tools and practices (whether they’re a part of Agile or not) that allow you to remain flexible and respond quickly and easily to changing requirements. Focus on frequent and candid communication with clients, and choose programming ideologies (like YAGNI and KISS) that commit the minimum code and architecture required to build what you’re making right now, without trying to plan six steps down the road. Ship early, ship often, get meaningful client feedback, and iterate.
A ton of ink has been spilled on this topic, so we’ll try to be brief here: Don’t estimate.
Reason #1: It’s impossible to do accurately. In a collective 50 years of software development, we’ve never met anyone who can consistently estimate a meaningful cluster of programming tasks to within an acceptable threshold of accuracy. When a process fails this consistently, it’s time to scrap it.
Reason #2: It’s wasteful. Why spend time on a failed process that could be spent doing the actual work? There’s no good reason.
Reason #3: It puts unhealthy pressure on programmers, which makes them stressed out and miserable. Every time a task takes longer than your estimate feels like a micro-failure. This accrues to make programmers feel like there’s something wrong with them, when we want them to feel creative, engaged, and happy. Out it goes.
But people are stubborn. They desperately seek clarity, so they endlessly try to rephrase or reframe the idea of estimation. A "t-shirt size" or "just a ballpark" or "just a high-level sense... I won’t hold you to it". Don’t do it.
If you have to give them something, give them an order of magnitude: "hours", "days", or "weeks". The estimate is usually for someone other than the person asking (e.g. a boss, a customer, a grantor, an investor), so you’ll have to help them figure out how to sell it. This isn’t easy, but it’s honest, human work, whereas making up numbers to appease someone does them a disservice.
When they help standardize workflows, ensure adherence to requirements, or save time, processes are good. Processes are great at helping to factor out boring, repetitive things. Processes are less good at encouraging behavioral change, but sometimes when we want to encourage a behavior we assume creating a new process is the only way.
Developing a culture — a shared set of beliefs, values and practices — is harder than developing processes, but culture’s impact can be more lasting, more consistent, and more naturally integrated than process. If every member of your team values accessibility, for example, they’ll consider accessibility throughout an entire project, not just at the final step when your process dictates an accessibility check.
Programmers need large blocks of uninterrupted time to do their best work. In theory, that sounds pretty easy to provide. Today, however, this need must be forcefully defended, or the programmer’s day will magically fill with meetings, check-ins, drive-bys, micro-distractions, chat pings, and 100 other types of interruption, all of which stand in direction opposition to deep, meaningful work getting done.
This is true for many kinds of deep work, but it's especially true for programming. Programming requires the practitioner to hold multiple pieces of information in their head in the crucial moments before those ideas can coalesce and pass through the keyboard. When they're interrupted, a programmer has to gather all those pieces together again when they return to the task, costing precious time and jeopardizing key insights.
When you see a server in a restaurant delivering a giant tray of precariously balanced dishes, do you walk up and tickle their nose? No, you give them a wide berth and let them do their job, lest all those carefully prepared dishes come crashing to the ground. Same with programmers. Don’t interrupt a programmer unless it’s actually important. Create structures where their communication tasks can be performed in the in-between moments, when they aren’t deep under the hood. Make sure everyone understands what constitutes "important enough to interrupt".
If you do client work, you’ll need a kickoff meeting for a new project, and you’ll probably need a regular meeting to deliver work. And some times you just need to get two people on a quick Zoom call to hash something out in a way that's faster and more collaborative than would be possible async. Beyond that, meetings should be steadfastly and ruthlessly eliminated, including the ubiquitous Daily Standup.
Meetings are costly (add up the hourly rate of every person in the meeting some time), disruptive (ugh, I was so close to a breakthrough, but I have a meeting), and have a nasty tendency to self-replicate (the last part of most meetings is scheduling the next meeting). In too many organizations, scheduling a meeting is used to give the illusion that work is getting done, when in fact the opposite is true: Nobody is getting anything done, because they are in meetings all day.
Experiment (either actually, or in your mind) with canceling every single meeting for a week, or a month. Did you get any less work done?
Every conflict offers a choice: This moment can be an opportunity for growth, or a chance to perpetuate unhealthy patterns by leaving crucial truths unspoken. Addressing conflict directly and honestly is good and healthy, in every area of life, and work is no exception. If there is something difficult that needs to be said to a colleague and you fail to say it, you have harmed your colleague in service of your own comfort.
By the same token, not every critique or suggestion you have for that colleague is actually important. Most, in fact, are not. Take great care in deciding which of these to communicate (particularly to direct reports or people junior to you), then do so with care and kindness, remembering you likely aren’t so perfect yourself either.
Build a culture of deep care and respect for the human beings at your clients. Approach each new client relationship with the goal of finding out what truly matters to them. Show them you want to understand by asking clarifying questions and checking back in with them on their big goals. If you sense stress or pressure, try to get to its source by talking to the person closest to the source. This approach positions you as a trusted partner for your client, who cares about their needs, and provides meaningful counsel in service of their goals. Be a partner, not an order-taker.
Treat clients not as sources of revenue, but groups of human beings with real problems that need solving. If your company can help with these problems, tell them. If you can’t, or you aren’t sure, or a certain need comes up against a growth edge of your firm, tell them that too. Focus on delivering maximum value for your client, even if this doesn’t mean maximum revenue in the short term. A client who trusts you and is happy to have worked with your company is far more valuable than one you juiced for maximum revenue.
If your client thought highly enough of your company to hire you, and you’ve treated them with respect, candor, and care throughout the relationship, you deserve their trust. There’s a certain type of person who feels it’s their job to be skeptical of outside vendors. On occasion they will subtly imply you’re not doing a good enough job, not working fast enough, or that you’ve been somehow less than honest. Don’t stand for it. Environments that lack a foundation of trust will eventually make your employees miserable. Politely but firmly tell this person that in order to do great things together, you require their trust. If they react poorly, or simply don’t agree, show your team you care for them by finding a new client who can extend trust.
Modern programmers, especially those working with open source tools, learn and grow largely through free resources, and we use free software every day in our day jobs. A company that profits from the work of educators and open source contributors owes it to the community to contribute back, whether financially or otherwise.
Give financial support to creators with Patreons and GitHub sponsor pages. Give educational support by teaching through podcasts, conference talks, and blog posts. Give code support by contributing to open source libraries you use, or writing and releasing your own. Support conferences, meetups, free bootcamps, and other community projects. Use the power, influence, time, and money that come from having a company to uplift and empower the community that enables you to do the work in the first place.
It's easy to point out when the communities we're in don't look the way we want, whether it comes to diversity, financial support, educational opportunities, or anything else. But as companies and organizations with financial and time resources, we actually have a chance to shape our communities to be the way we want instead of simply complaining about what they're not.
The best programming communities are those which are good for the people inside them (and the people who are joining). That means they're welcoming, friendly, collaborative, healthy, and safe. As leaders in our communities we can use our time, energy, and money to help this come to fruition.