When my team at Temple started talking about building our own CRM, the first reaction from outside the room was always the same: why? Salesforce exists. HubSpot exists. There are companies whose entire business model is "we'll do this for you." Why would a university IT services group spend a year of engineering time building one from scratch?
The honest answer is that the off-the-shelf CRMs were never quite built for what we needed. They assume a customer pipeline — leads, opportunities, deals — and a university doesn't have customers. It has students, and a student's relationship with the institution is a multi-year affair with very different shape than a sales funnel. By the time we mapped our actual workflow onto a vendor CRM, half the screens were hidden, half the fields were renamed, and the integrations with our central registration system were brittle in a way nobody enjoyed maintaining.
So we built our own. Here's what I learned.
The 80/20 of CRM features is brutal
Going in, I assumed we'd need to build something like Salesforce Lite. Lookups, dashboards, custom fields, automations, the works. The first version had most of that. The version people actually use, eighteen months later, is dramatically smaller:
- Search. Find a student. By anything.
- A single record view that shows the timeline of everything we know about them.
- Notes. Free-text, dated, attributed.
- Send an email, with templates the team can edit.
That's roughly 80% of usage. Everything else — dashboards, custom segments, automations — is useful, but it's a long tail. Knowing that earlier would have saved me about three sprints.
Integrations are the actual product
A CRM that doesn't know what's in your registration system is a glorified address book. The interesting engineering at Temple isn't the CRM itself — it's the API surface between the CRM and the half-dozen other systems it depends on. Grades, enrollment, course history, financial aid. Each has its own owner, its own data model, and its own ideas about who's allowed to read what.
The CRM is the interface. The integrations are the work.
I ended up writing more Flask in the last year than PHP, which is funny because the CRM is a PHP app. Most of my time went into small Python services that move data between systems on a schedule, validate it, and surface a tidy, predictable view to the CRM. The grade-transfer endpoint, for example, replaced a process that involved a human downloading a CSV, opening it in Excel, and re-uploading it elsewhere. The new version is one HTTP call and a webhook. No CSV, no human, no Excel.
Observability before features
The single most useful thing I did all year was set up Grafana before we shipped the second release. Once we had real-time dashboards on response times and error rates, every conversation about "what should we build next" became a different conversation. We stopped guessing and started looking at graphs.
Our incident response time dropped 25% — but the bigger win was that the team's intuition about what was slow started matching reality. We'd been wrong about a lot of things.
Build for the boring case
The thing nobody tells you about internal tools is that they get used by people who are tired. It's 4:47 PM on a Thursday and the registrar's office needs to email a cohort of 200 students before close-of-business. The CRM doesn't need to be elegant. It needs to do that one thing, fast, without surprises.
The longer I work on this kind of software, the more I think great internal tools and great consumer products look almost nothing alike. Internal tools should be a little boring, in the way that a good kitchen knife is boring. You should be able to use it without thinking about it.
What I'd do differently
If I were starting over: I'd write the integrations first, and let the UI come later. I'd commit to one data model — the registration system's — and shape the CRM around it, rather than trying to make the CRM neutral. And I'd ship a feature-flagged early version to one or two users weeks earlier than I felt ready, and let them tell me what was wrong with it.
Building software in a university is a slow, accumulating kind of craft. Most of it isn't glamorous. But once a year you watch a team of three people do, in twenty minutes, what used to take them a full day — and you remember why this kind of work is the work.