Final project progress outreachy

August 25, 2025

Person

Hi everyone! In this post, I’ll walk you through my internship journey with Servo as part of the Outreachy program. I’ll share what we’ve achieved so far during the internship period and the lessons learned along the way.

What is Servo?

Before diving into the details, let me introduce Servo. Servo is a prototype web browser engine written in Rust and is currently under active development. As of this post, it has 61.8% Web Platform Test coverage

Web Platform Tests (WPT) are a cross-browser test suite that checks how well browsers implement web standards. Simply put, WPT checks how many Web APIs a browser supports correctly, giving an idea of how complete its web platform implementation is.

The Problem Statement

Like many large-scale software projects, Servo uses GitHub Actions for continuous integration (CI) to validate pull requests. One key step in the CI pipeline is linting, which identifies issues such as verbose or suboptimal code, use of outdated APIs, unsafe API usage, and code that doesn’t follow Servo’s style. The goal of my internship work was to fix this and make the linting experience more helpful for both new and experienced contributors.

My Work

The Challenges

Adopting Pyrefly has some challenges. It follows design patterns strictly, which is better than other type checkers in some ways, but it also has trade-offs.

For example, in Pyrefly you are not allowed to change the name of a signature of a method from the parent class. This is by design, according to their docs here

The guiding idea here is the Liskov Substitution Principle, the idea that a subclass can stand in for a base class at any point without breaking the program.

This rule can cause a program to crash. You might argue that this is not a significant issue because it’s uncommon to use keyword arguments when calling a class method, most people only care about positional arguments. Consider the following example:

class Base:
def f(self, a: int) -> None:
pass
class ArgsWithDifferentName(Base):
def f(self, _a: int) -> None:
pass
def uses_f(b: Base) -> None:
b.f(a=1)
uses_f(ArgsWithDifferentName())

Here, renaming the parameter in the subclass will cause a runtime error when using a keyword argument, demonstrating Pyrefly’s strict enforcement of method signatures.

Gratitude

This internship journey with Servo would not have been possible without the guidance of my mentors, Martin Robinson and Mukilan Thiyagarajan.

They played a key role in helping me navigate the codebase, from reviewing my pull requests to sharing practical advice during our meetings. Their support not only made my contributions possible but also shaped how I approach problem-solving in large-scale open-source projects.

I would also like to thank the Outreachy organizers, especially Omotola E. Omotayo, for hosting regular check-ins and fostering a supportive space for all interns throughout the program.

I’m deeply grateful for this experience and excited to carry these lessons forward in my open-source journey.