Three books changed my life as a programmer. Kernighan1981 taught me that I could do more than just write software—I could design it—while Glass2002 taught me that we could investigate software and software development scientifically, and by doing so discover what actually works and what doesn't.

In between those two books I read Hunt1999, as did many other programmers of my generation. For many of us, it was the first time someone had described the craft of software construction in a way that made sense. When I began supervising undergraduate projects at the University of Toronto in the early 2000s, I referred to it over and over again.

Looking at it and at its twentieth anniversary edition Thomas2019, I am struck by how useful it continues to be, but also by what it doesn't discuss. How do you run a meeting in a way that ensures decisions actually get made and everyone is heard? After working in tech for forty years, I believe that is the most important skill I ever learned. Why and how do tech companies build products that people don't want? Why do they marginalize women, people of color, and members of the LGBT community despite all the evidence showing that more diverse teams are more productive? And given how online platforms have fueled radicalization and disinformation in ways that threaten us all, shouldn't every guide to being a better programmer at least mention the problem?

If you are an undergraduate student embarking on a semester-long software project as part of a team, this book will give you tools that will help you succeed. Some of these are purely technical, like a version control system or an IDE; others are guidelines to help you form teams, manage people who aren't pulling their weight, cut features when time runs short, and understand who owns the things you produce.

Our aim is to teach you how to be a compassionate programmer: one who cares as much about the well-being of their colleagues and users as they do about their own. This focus is not entirely altruistic—everything you do to help others also helps your future self—but now that we all know how much harm software can do, we hope you'll be interested in some practical idealism.

All proceeds from this project will go to support the Red Door Family Shelter.


Every lesson should be written with specific learners in mind. These personas are ours:

Like these personas, readers should:

This book can be read on its own or as a companion to Software Tools in JavaScript, which teaches the basics of software design by showing you how to build the tools you program with. If you are looking for a project to do in a course, adding a tool to those covered there would be fun as well as educational.


Life is short and your project is even shorter, so this book focuses on the handful of tools and techniques that will help you the most in the short and medium term:

We have included other material as well, since there is a lot of variation between project courses (and even more between the people doing them). Throughout, we are guided by a modified version of Dobzhansky's Rule:

Nothing in software engineering makes sense except in the light of psychology.

Many of the hard problems in software engineering stem from the fact that human beings think and feel, and we do those things in certain ways. Our mental capacity is limited, which means we have to design programs so that they will fit into the space between our ears. We learn and work better when we are doing things that help us meet our personal goals, which means projects will be more successful if we take motivation into account. And as we learn more, the best way for us to learn changes in predictable ways, so how we are taught should change too.

Using and Contributing

All of the written material on this site is made available under the Creative Commons - Attribution - NonCommercial 4.0 International license (CC-BY-NC-4.0), while the software is made available under the Hippocratic License. The first allows you to use and remix this material for non-commercial purposes, as-is or in adapted form, provided you cite its original source; the second allows you to use and remix the software on this site provided you do not violate international agreements governing human rights. Please see for details.

If you would like to improve what we have or add new material, please see the Code of Conduct in and the contributor guidelines in . If you have questions or would like to use this material in a course, please file an issue in this site's GitHub repository or send us email.


This book is dedicated to Marian Petre, who taught me that not everything worth studying can be measured, and to Tom Wilkie, who taught me that an author's job is to create the manure in which an editor grows something worth reading. I am also grateful to all of the students who did projects with me at the University of Toronto and through Google Summer of Code, and to everyone who took part in UCOSP Holmes2014,Holmes2018.

I have tried to base recommendations on empirical software engineering research () and on the science of teaching and learning (). Where those don't have answers, I have drawn on the experience of the students and programmers mentioned below. Any errors, omissions, or misunderstandings that remain are entirely our fault.

Bram AdamsRohan AlexanderTavish Armstrong
Titus BarikRobert BeghianYanina Bellini Saibene
Neil C C BrownJordi CabotSilvia Canelón
Francisco CanasMike ConleyMichael DiBernardo
Isaac EzerIan Flores SiacaAdam Goucher
Mustafa HaddaraJohan HarjonoKate Hertweck
Daniel JacksonJacob Kaplan-MossRitu Kapur
Zain KazmiLaurie MacDougall SookrajDarren McElligott
Kim MoirNatalia MorandeiraMeiyappan Nagappan
Iain ParrisElizabeth PatitsasAndrew Petersen
Andrey PetrovAndrew PotapovLutz Prechelt
Yim RegisterEvan SchultzAlex Serebrenik
Naaz SibiaAndreas StefikRory Tulk
Blake WintonAndy ZaidmanAndreas Zeller

Portions of this book are adapted from material that originally appeared in Sholler2019,Wilson2019,Irving2021,Smalls2021; I'm grateful to Taylor & Francis, PLOS, and my co-authors for making available under open licenses. I would also like to thank David Graf for doi2bib and Alexandra Elbakyan for Sci-Hub; this book would have been much harder to write without their idealism and hard work.