<aside> đź“ť

Tom Mitchell (Head of Engineering) - October 31, 2024

</aside>

Building a Developer-First Engineering Culture

In a startup environment like ours, developer productivity is king. We are pumped about our mission and the real impact that we can have on peoples’ lives as they navigate a complex healthcare system, and we want to make sure we arrive at that vision as quickly as possible. It’s critical that we get process and tooling out of the way so that our developers can focus on building a great product.

At Medbill AI, we've built a software development environment that prioritizes efficiency without compromising quality or structure. Our carefully curated stack and engineering processes reflect our commitment to developer empowerment and delivering high-quality, reliable software. Let’s dive into the philosophy behind our choices, the tools we’ve adopted, and what it’s like to work in this kind of environment day to day.

Our Process: Lightweight, But Structured

We believe in maintaining a lightweight but structured development process—one that allows for agility and rapid iteration without devolving into chaos. It’s a delicate balance between empowering developers and ensuring high standards, and we never want to introduce process for process’ sake. There’s also something to be said for flexibility—we will continue to evolve our process to meet the needs of the organization over time.

A typical week is structured around lightweight sprints: we kick off with sprint planning, dive into focused work, and by the week’s end, review what we’ve achieved. This rhythm helps maintain momentum, and developers can focus on delivering features and improvements without feeling overwhelmed by processes. As a remote-first company, it’s also crucial that we have a regular touchpoint as a team, so we do a daily standup session for tactical and organizational updates.

Good task tracking is pivotal, and we use Linear for issue tracking and sprint management. It provides a clean, no-nonsense interface for keeping the team aligned on current work and priorities. Sprint planning becomes less of a chore and more of a time to focus on high-impact work.

For us, Notion serves as the nerve center of documentation and collaboration (and the platform this very blog post is published from!) We maintain a comprehensive wiki that covers every part of our stack in detail and is really geared towards helping every new engineer hit the ground running on day one. In addition, our lightweight design doc process captures important decisions in a transparent and accessible way, ensuring requirements are aligned, and historic decision-making is recorded. This is a critical aspect of fostering productivity—developers can easily onboard to new projects or tasks without hunting for context.

A few times a year, we travel somewhere unique for an onsite (previously New York and New Orleans), focusing on deeper collaboration that can be harder to achieve remotely. These sessions offer the chance to make architectural decisions, reflect on how we function as an organization, and bond as a team. It’s not just about productivity—it’s about building a fun and invigorating engineering culture.

We also believe in fostering innovation outside of daily tasks. We are working on the cutting edge of the new AI landscape where everything is advancing rapidly, so we need room for experimentation. Hackathons allow our teams to explore important technical explorations or spike on new ideas. These are opportunities to experiment, learn, and occasionally stumble onto our next big breakthrough.

Codebase and Tools: A Productivity Powerhouse

Our approach to tooling and the codebase reflects our goal of maximizing productivity while enforcing best practices. We’ve chosen technologies that make everyday tasks easier, encourage maintainability, and create a seamless experience for engineers moving across the stack.

The first crucial feature of our codebase is that we utilize TypeScript top-to-bottom, to encourage engineers to move effortlessly across our stack. We love the added safety of a statically typed language, while not going all the way to the rigidity of a language like Go or Rust. And yes, we use TS strict-mode.

We’ve adopted a monorepo structure, keeping all of our code in one place. This reduces hidden dependencies and ensures that any changes made in one part of the system are immediately visible across the entire codebase. We want to avoid any cross-team siloes, and minimize the risk of integration issues cropping up unexpectedly. To keep this large monorepo manageable, we use Nx, which acts as a lightweight build system—managing dependency graphs and caching build artifacts to help keep things performant.

Onboarding or setting up a new environment can often be a time-consuming process. Not here. We’ve standardized our development environment using VSCode Dev Containers. This ensures that every developer has a repeatable, zero-setup environment which has everything they need to hit the ground running on day one.

We take continuous integration seriously. With GitHub Actions, we have full confidence that every commit that lands has been rigorously validated. And before anything even makes it to CI, our git hooks enforce opinionated formatting and linting rules, preventing low-quality code from slipping through the cracks.

We love Github, but we also leverage Graphite for stacked PRs, allowing developers to break up their work into smaller, more manageable changes that can be reviewed independently. This leads to faster, more focused code reviews and, ultimately, fewer bugs. Plus, we know the CEO (Merrill from Oscar), so we have a direct line to influencing this tool’s evolution—always a bonus! They continue adding a ton of features—for example, we have had fun playing with their AI reviewer recently.

Frameworks: Best-In-Class for Every Use Case

When it comes to frameworks, we’ve selected the best tools for the job across the entire stack.