Concepts — Contributing to Chromium

Phase 6 · Spec areas §24 (contribution workflow), §49 (OSS portfolio). Requires a working build.

Verify everything here against current upstream docs/ before acting. Contribution process changes, and a stale instruction wastes a reviewer's time — which is the one cost that matters in an open-source contribution.


1. Why a Principal Engineer needs this

Landing a change in Chromium is a credential, but the reason it belongs in this track is narrower and better: it forces every other skill to be real. You cannot land a fix without locating the subsystem, understanding the invariant, writing the right test, and defending the design to someone who owns the code. Reading Blink is unfalsifiable; a CL is not.

It also teaches something you cannot learn from your own codebase: how to make a change in a system you do not own, for reviewers who owe you nothing. That skill transfers directly to cross-org work at Principal level.


2. Mental Model

2.1 The pipeline

find a bug  ->  reproduce  ->  locate subsystem  ->  minimal failing test
   ->  fix  ->  local tests  ->  git cl upload  ->  Gerrit review
   ->  OWNERS approval  ->  presubmit + try jobs  ->  CQ  ->  landed

Facts that shape the work:

  • Issue tracker: issues.chromium.org. (Chromium's own docs/contributing.md still contains a bugs.chromium.org reference — treat in-tree docs as authoritative but not infallible, and prefer what the live site does.)
  • CLA required; first-time contributors add themselves to AUTHORS.
  • Review happens in Gerrit (chromium-review.googlesource.com), not GitHub PRs. One change = one CL, revised as patchsets, not as new commits.
  • OWNERS approval is required per affected directory. git cl owners suggests reviewers. Committers need one Code-Review +1; non-committers need two.
  • Presubmit runs on upload; try jobs compile and test across platforms. A CQ dry run is how you check before asking for a human's time.

2.2 Choosing the change

The ladder from the specification, with what each actually teaches:

RungChangeTeaches
0Build Chromiumtoolchain, targets, iteration
1Docs or test-onlythe process end to end, at low risk
2Small isolated correctness fixlocating a cause; minimal reproduction
3Blink behaviour bug + regression testspec → test → implementation, the core loop
4Small rendering/style/layout improvementsubsystem depth, performance argument
5Cross-component changeMojo boundaries, multiple OWNERS, design review

Do rung 1 before rung 2, even though it feels trivial. The first CL's difficulty is entirely process — CLA, git cl, Gerrit conventions, presubmit, try-job failures unrelated to your change. Learning that with a doc fix costs a day; learning it while also defending a behaviour change costs a week and a reviewer's patience.

2.3 Where to find work

  • TestExpectations (bi-13) — documented, accepted, currently-wrong behaviours with bugs attached. This is the best-quality source of rung-3 candidates in the tree.
  • Failing WPTs in a subsystem you have studied.
  • The issue tracker, filtered to components you know. Look for hotlists aimed at new contributors; verify the current label names on the live tracker rather than trusting any written list, including this one.
  • A bug you actually hit. The strongest motivation and the best reproduction.

Choose a bug in a subsystem you have already studied in this track. A contribution is not the place to learn the subsystem.

2.4 What reviewers actually check

In rough order:

  1. Is the behaviour correct per the specification?
  2. Is there a test that fails without the fix?
  3. Is it at the right layer, and does it fit the subsystem's design?
  4. Ownership/lifetime correctness (bi-06).
  5. Style, naming, and git cl format.
  6. Does it need a flag, a metric, or a spec discussion first?

Item 6 catches people out: a behaviour change visible to the web may need a launch process, metrics, and standards-body agreement — not because Chromium is bureaucratic, but because unilateral behaviour changes break sites and interop. If your fix changes what the web sees, expect the conversation to be about compatibility, not correctness.


3. Practice

Verify against your checkout's docs/contributing.md and the linked process docs. The mechanical parts (git cl upload, git cl format, git cl owners, CQ dry run) are stable; the surrounding policy is not.

Keep a record per attempt — the specification asks for exactly this, and it is what turns a contribution into learning:

bug · reproduction · spec · suspected subsystem · source path · call path
· test · proposed fix · reviewer feedback · architectural lesson

3.5 Deep dive: the web-visible change process

Rung 3 and above frequently touch behaviour the web can observe. That is a different process from a bug fix, and not knowing it is the fastest way to have a technically-correct CL stall for months.

The shape of it:

idea  ->  spec discussion (WHATWG/W3C issue, or a explainer)
      ->  design doc, if non-trivial
      ->  UseCounter metrics: how much of the web actually does this?
      ->  intent-to-prototype  ->  behind a flag  ->  origin trial (sometimes)
      ->  intent-to-experiment / intent-to-ship on blink-dev
      ->  API owners' approval
      ->  ship, with metrics watching for regressions

The single most important artefact in that list is UseCounter. Blink instruments feature usage and aggregates it across the web, so questions like "how many page loads use this quirk?" have a real number attached. A removal proposal without usage data will not proceed.

This is the part that most surprises engineers arriving from product work. In a product you change behaviour and watch your own metrics. Here, "correct per spec" is necessary and not sufficient — you must also show the web will survive it. Compatibility is a constraint of equal weight to correctness, and arguing otherwise marks you as someone who has not internalised the problem.

If your fix changes what pages observe, expect the review conversation to be about compatibility and data, not about whether you read the spec correctly.


3.6 Deep dive: what makes a CL easy to approve

Reviewers are rationing attention across many changes. Optimise for their time, not yours.

Structural:

  • One change per CL. A fix plus a refactor plus a rename is three CLs.
  • Small. A first CL over ~200 lines is asking a stranger for a large favour.
  • Test first in the description: state what fails without the fix.
  • git cl format before every upload; never spend credibility on whitespace.

In the description:

  • What the bug is, in one sentence a non-expert can follow.
  • Why this layer is the right place to fix it — pre-empting the most likely objection.
  • What you considered and rejected. This converts "why didn't you just…" into "they already thought about it."
  • Bug: footer, always.

In the code:

  • Match the newest pattern in the file, not the nearest (bi-06: migrations in progress).
  • Add a DCHECK stating any new invariant.
  • Correct handle types (Member vs raw_ptr vs unique_ptr) — the most likely substantive comment.

Handling review feedback

  • Reply to every comment, even if only "Done."
  • If you disagree, say so once, with reasoning, and ask a question rather than restating.
  • If a reviewer wants a design change you think is wrong, ask what failure mode they are protecting against. Usually they know something you do not; occasionally the question reveals they misread. Either outcome is progress.
  • Going quiet is worse than being wrong. An abandoned CL costs the reviewer more than a bad one.

3.7 Deep dive: how to pick a first bug that will actually land

Bad first bugs share a shape: they are interesting. Interesting bugs are unfixed because they are hard, contested, or blocked on a design decision.

A good first bug:

  • is in a subsystem you have already studied in this track,
  • has a reliable reproduction,
  • has a clear expected behaviour, ideally spec-defined or in TestExpectations,
  • is small — one file, one behaviour,
  • is not load-bearing for a feature someone is actively rewriting (check git log for recent churn in the directory — heavy recent activity means you will conflict with a bigger change).

That last check takes thirty seconds and saves weeks:

git log --since=90.days --oneline -- <directory> | wc -l

A directory with a hundred commits in ninety days is being actively rewritten. Pick elsewhere for your first CL.


3.8 Deep dive: the record to keep, and why

The specification asks for a record per contribution. Here is why each field earns its place:

FieldWhy
bugthe problem, as the project sees it
reproductionthe thing you will lose first if you do not write it down
specwhat should happen, independent of any implementation
suspected subsystemyour prediction — score it later (bi-01 discipline)
source path + call paththe navigation, so it transfers
testwhat would have caught this
proposed fixincluding alternatives rejected
reviewer feedbackthe highest-value field
architectural lessonwhat you now believe that you did not before

Reviewer feedback is the field to protect. It is the only part of this you cannot generate yourself: a domain expert telling you what you missed, for free, on your own work. Most engineers read it, fix the code, and forget it. Writing it down converts a code review into a durable lesson.

And write the record for rejected CLs too. A rejected CL with a clear architectural lesson is a successful lab; the goal of rungs 1–3 is competence, not a merge count.


4. Anti-Patterns

A first CL that is large. Reviewers ration attention; so should you.

Fixing a symptom at a call site because the real cause is in unfamiliar code.

Arguing with a reviewer about style. Run git cl format and spend your credibility on substance.

Changing web-visible behaviour without checking compatibility. Expect to be asked for usage metrics and interop evidence.

Going quiet after review feedback. An abandoned CL costs the reviewer more than a bad one.

Starting at rung 3 to skip the boring parts. The boring parts are where the process failures live.


5. Trade-offs

Small safe changes vs meaningful ones. Rung 1 teaches process and nothing else. Rung 3 teaches the subsystem and risks stalling. Do both, in order.

Fixing vs filing. A well-written bug with a minimal reproduction is a real contribution and sometimes the better one, especially when the fix requires design agreement you cannot yet obtain.

Chromium vs WPT. A WPT contribution needs no C++, improves every browser, and lands faster. For an application engineer it is frequently higher leverage — and it is the right rung-1 alternative if a doc fix feels too trivial.


6. Lab

  1. Rung 0 — a build that runs. (Blocked here; see the roadmap's build guide §2.0.)
  2. Rung 1 — land a docs or test-only change. Goal: complete the process once. Record every step that surprised you.
  3. Rung 2 — from your bi-13 candidate list, pick the smallest defensible correctness fix. Write the failing test first.
  4. Rung 3 — a Blink behaviour bug with a regression test, in a subsystem you studied.
  5. Maintain the record above for each, and write the architectural lesson even when the CL is rejected. A rejected CL with a clear lesson is a successful lab.

7. References

  • docs/contributing.md in your checkout — the authority.
  • docs/cl_tips.md, docs/code_reviews.md, and the OWNERS documentation.
  • issues.chromium.org — the live tracker.
  • The Chromium blink-dev process for web-visible behaviour changes (intent-to-ship and friends).
  • web-platform-tests contribution guide.

8. Principal Engineer Review

  1. Your fix is correct per spec but would break a measurable fraction of sites. What happens next, and what is your role in it?

  2. A reviewer asks for a design change that doubles the work and you think it is wrong. How do you handle it, and what would change your mind?

  3. Argue that a well-written bug report is more valuable than a mediocre fix. Give the case where it is not.

  4. Chromium requires OWNERS approval per directory. Argue this scales; then name its failure mode and what you would do as an owner to mitigate it.

  5. You have one week of a team's time for open-source contribution. Chromium, WPT, or a framework? Justify from leverage, not from prestige.

  6. Your CL sits unreviewed for three weeks. Enumerate your options in order of escalation, and say which you would actually use.

  7. What makes a change "cross-component," and why is that qualitatively harder than a large change within one component?

  8. You are onboarding an engineer to contribute upstream. Design their first month. What do you deliberately not let them do yet?