How to Build a World Class Engternship Program
Software internships are broken, but they don't have to be
At my last company, Tenet, I built a program that took early career engineers with 0-1 years of experience and turned them into competent, independent, intermediate engineers over a 3 month trial period. I originally created the program because I had a lot of work that needed to get done on a slim budget, but I kept doing it because it was so effective.
Since then, I have spoken to a lot of founders and engineers about their experiences with internships or junior placements, and a lot of startups are doing it really wrong.
In this post, I’ll explain why the industry standard internship is bad (for everybody involved), I’ll talk about what makes a successful startup internship program, and I’ll detail the specific structure of my program (which we affectionately called the “Engternship”) so that you can stop flopping with junior engineering hires.
Quick note: I’ll refer to interns and juniors and internships and junior placements interchangeably throughout (sorry!).
A Caveat
After writing this post, I realized that I was taking something for granted - I believe you can only have and sustain high performing engineering teams when engineers are happy and engaged. Some of the methods in here sound a little cold. They are, and they work, but they (probably?) only work on healthy teams - they definitely won’t fix bad engineering culture.
Big Tech Internships Don’t Work for Startups
After speaking with dozens of engineers, I always hear about the same kind of SWE internship. The intern is brought on for 3 or 4 months, given a side project that the team hasn’t gotten to yet, given very little direction or feedback, and then released back into the wild. Maybe they get some code review, and once in a blue moon the team will actually use the project that they built, but for the majority of the internship the intern is flapping in the wind.
Here are some signs that you shouldn’t hire an intern:
You don’t have a lot of important work that needs to be done.
This probably indicates that you are failing or you have over-hired, and you should be firing.
You are incapable of substituting 4 hours of junior level work for mentorship across your more experienced engineers.
This almost certainly means that your team is unbalanced and you need to hire more experienced engineers.
Your engineering team is un-opinionated, unstructured, or has poor consensus around best practices.
This is a non-starter for more junior engineers - most will fail almost instantly. You likely need better engineering leadership, or you’re just too small.
You aren’t planning to bring them on full time.
Showing results for: contractor? Why would you hire someone who can’t code very well, teach them a bunch of skills, and then let them go?
If you are expecting to bring on someone who has practically zero experience and then have them contribute productively to your codebase without interacting with them or setting clear guidelines for success… Well, that’s just pretty entertaining. This is obviously a joke, right?
Unfortunately, it is actually the state of many industry internships. In my opinion, it’s because a lot of startups think that they ought to have interns, or see juniors as a way to get cheap labor, but they haven’t thought deeply about how to set them up for success. Instead, the go-to model is the big tech internship, which for FAANG companies is a way to attract the best CS grads, but for startups is a massive waste of time and energy.
A Successful Engternship is About Growth
For junior engineers, the number one important thing in a placement is experience. Not just a dated resume line item, but growth, learning, and opportunity to work on interesting things. The ability to level up quickly and learn the skills to be successful will transfer across jobs and often into the job hunt. I can tell how engaged an engineer was at their prior job based on the breadth and depth with which they can describe their experience, and it makes a world of difference if they index high on both of those axes.
Set Expectations Early and Clearly
In order for juniors to succeed, they need clear structure and expectations. When talking to candidates, I would clarify role expectations in the first interview and again on the first day, as well as in a written “How to be Successful” packet. Having clear success metrics and transparent measurement also made the burden of evaluation significantly lighter - I wanted to minimize the management overhead. Feedback is very important, but doesn’t need to be constant - early and rigorous code review goes a long way to set the tone for a placement, and beyond that a weekly touchpoint works.
Treat Interns as a Full-Time Hire-In-Training
For startups, a successful junior placement looks like any other engineering hire - a lot of productive work done, fast growth, and high velocity. Minimal training overhead is important, but expect that there will be some feedback over and above what’s usual for an experienced engineer. An extremely successful internship program should result in a full time, intermediate level engineer for a bit cheaper than you could hire one in the market, and who already knows your systems and processes.
Get to “Yes” or “No” as Fast as Possible
It’s also super important to know quickly whether or not that junior is going to be a success. Juniors are one of the hardest roles to hire for, specifically because their technical abilities are relatively commoditized and their success depends largely on their ability to grow, which is much harder to measure in interviews. You can typically tell in a high feedback, high throughput, structured environment if a junior engineer is going to be successful within a couple of weeks.
There’s a lot of overlap in what’s important to a startup and what’s important to a junior. Both want impact and growth. The junior may need to shovel some uninteresting tasks that nobody else wants to do, which is part of the job, but it is better for everybody if the junior engineer learns quickly and contributes meaningfully.
How to Build a Successful Engternship Program
Communication is everything as a manager, and it’s important to be clear and upfront with incoming employees. If you’re going to run a rigorous early employee program, make sure that you tell candidates as early as possible. Transparency serves as a good filter as well - when I told candidates that we let go of 40% of engterns before the 3 month trial period ended, if they were excited by that challenge it was a strong positive sign. Many candidates also self-selected out of that, which saved us a lot of time and headache.
Ship, Ship, Ship
Starting day 1, the expectations are set to ship a PR. Well, they have to set up their computer, right? Yes, and they also need to put up a pull request. After that, every day requires 3-5 fresh pull requests. The rare day of 2 PRs is acceptable, particularly if one of the PRs is fairly large or if there are blockers, but repeatedly shipping only 2 PRs per day is unacceptable, and 0 or 1 is a non-starter. The all-time record for an engtern was 9 PRs in a day.
In order to get this level of performance from a junior engineer, there has to be a baseline level of support - good onboarding, good ticketing, and good unblocking.
Onboarding
The onboarding process needs to be seamless. This is a good rule of thumb for engineering teams in general - if a junior engineer can’t set everything up in an hour or two, then you definitely need to revisit your onboarding process. You should also include expectations, common resources, and suggested readings in an onboarding packet. Every onboarding is an opportunity to improve onboarding.
Ticketing
The junior engineer needs to have a growing list of tasks on day 1 that they can draw from. I recommend creating a backlog where teammates can toss smaller, non-urgent, junior shaped tickets and low or medium bugs. This allows a junior to get used to grooming and maintaining a backlog, and also means they can’t say, “well, I didn’t have anything to do.”
Office Hours
There has to be structured time to answer questions. At Tenet, we set up Office Hours every morning and had a different senior engineer host. Engterns were expected to write down all of the questions they had over the course of the day and any blockers in their notebooks, and bring them to the senior engineers during office hours. A notebook prevents juniors from getting caught up in question ping-pong so that they can focus on getting work done, but also allows them to clear up any lingering questions they have and get unblocked. It also means seniors aren’t constantly swamped with silly questions.
Turbocharge Culture
Healthy engineering culture is critical for performance. It’s also nice to, I don’t know, enjoy your job? At a startup, where it’s not uncommon to spend more time at work than anywhere else, it is particularly important to have a good time. There are a lot of different ways you can set up a fun and engaging environment (gaming, inside jokes, lunch and learns, etc), but the aspects of culture that contributed the most to successful engternships were cohorts, pair programming, and the concept of ownership.
Cohorts
If possible, I highly recommend cohorting your engterns. Internships can be really lonely, and having a couple of interns come on at the same time means that they will naturally bond over the course of the trial period. At Tenet, cohorts made their own group chats and had their own inside jokes, and it was awesome to see how much they enjoyed working with each other. Engineers who had previously gone through an engternship would treat current engterns as protegees, resulting in a kind of alumni-student relationship. I didn’t expect this to happen when I started the program, but it was a really awesome externality.
Originally, I set up cohorts so that engterns would be competitive, and that worked really well. They competed on who would ship the most PRs, take on the most complex projects, and solve the hardest problems. Cohorting is a powerful tool for both learning and benchmarking - it’s much easier to compare against your peers than it is against yourself, and you work together to solve common problems and share knowledge.
Pair Programming
Pair programming is useful for context transfer and rubber duckying, but it’s particularly helpful when junior engineers drive in the presence of a more senior engineer. Often juniors have weird habits that slow down their development process, like not knowing a really common keyboard shortcut or copying console.logs everywhere instead of using breakpoints. Having a senior engineer just watch them and ask questions can teach them things that have compounding effects on their development speed.
Ownership
Ownership was extremely well-defined at Tenet. Having clear code and system owners helps structure who is responsible for what metrics, and where requests go to (first). It also means that you can rely on the owner of a system to manage that workload, and ask for help if it’s becoming overwhelming. If a particular system or product is not doing well, you know who to go to and why. For juniors, clear ownership serves as a built-in human router, they know exactly who to talk to if they are dealing with a new system or a sneaky bug.
Ownership also allows you to bite off something small, and hand it off to juniors to own independently. The classic example for us was our CMS - we often had requests to add new blog components or spin up partner pages, and an engtern would own that system. They would be responsible for independently managing those requests and completing them from start to finish, which taught them a lot of skills like scoping, estimates, prioritization, stakeholder management, asking for help, and so on - things that you would typically expect from a more senior engineer.
Close the Feedback Loops
If you hire a junior and end up spending all of your time managing them, it’s not a good tradeoff. You need high fidelity, low overhead ways to measure performance. If you can spend 5 minutes a day or less checking in on their performance with a relatively good read, that’s a win. For this, I recommend self-publishing metrics and regular reviews with clear and direct feedback.
Publishing Metrics
At the end of each day, it’s important to hit a certain number of PRs. I chose net new PR count as the leading metric for juniors because it’s straightforward to measure, it’s hard to fake (and easy to call out), and it squashes a lot of issues that early engineers usually face. The most common mistakes I see early engineers make are:
They are afraid that their code will be bad, and they will be embarrassed, so they rework it and don’t ship.
They get stuck on new domains or advanced patterns, and don’t ask for help.
They ship code in very large PRs, which are difficult to review.
They spend too much time “researching” the best implementation.
PR count is a forcing function that requires them to drop these habits on day 2, or they fail. It also pushes them to reflect on how they can speed up their development process.
In order to measure the PRs, I set up a slack channel where, at the end of each day, an engtern would post a link to each of their PRs. Then I set up a zapier that piped that into an excel sheet, which aggregated the number of github links by message date and sender. An end-of-day check-in made it easy to see how many PRs an engtern put up that day, but it also made it really easy to jump into links and review them, look back at progress over the last month, compare across engterns, and identify trends.
With just a couple of minutes at the end of each day, I could see any engtern who didn’t meet their PR quota, and help them troubleshoot. If underperformance became a consistent issue that couldn’t be resolved with some extra help or appropriate feedback, I’d give them clear feedback twice, a clear and final warning, and then I would let them go.
At the end of the week, all engineers, not just engterns, posted an update with their top PRs, what they learned that week, blockers, things that were particularly helpful, and suggestions to improve. A weekly, public review made it really easy to check in on the team and for engineers to transfer context across each other.
Performance management is arguably easiest for juniors, because code velocity ends up being such a good proxy.
Wrapping Up
The internship structure that I’ve outlined worked for me, at my company. This is probably not the final form, and it is certainly not the best internship program ever designed. It might not even work at all at your company. It was a highly successful internship program though, and it was successful because I thought deeply about how to set up engineers for success. You can do that too, and hopefully you can borrow some of my tips and tricks.
When you’re designing your engineering organization, think about how to set up your team for success. What does it mean to be a successful engineer? How do you get feedback and track the health of your engineers and your organization? How do you identify problems and continuously improve?
Working with Me
If you’re a founder or engineering leader and you want to set up a successful internship program or collaborate on org design that’s right for you, I’m happy to help.
If you’re interested in hiring high performing, “batteries-included” junior engineers (or becoming one), I’m currently working on taking the learnings from the engternship structure and applying them to an in-person software bootcamp in NYC. Please reach out if that sounds interesting to you.
You can reach me here.