Back to Articles

How Rust Governs Itself: Inside the RFC Process That Shaped a Language

[ View on GitHub ]

How Rust Governs Itself: Inside the RFC Process That Shaped a Language

Hook

Every feature in Rust—from async/await to const generics—began as a Markdown file in a GitHub PR. The rust-lang/rfcs repository isn't code; it's the constitutional framework for one of the fastest-growing programming languages.

Context

Programming languages typically evolve in one of two ways: through benevolent dictatorship (Python's Guido, Ruby's Matz) or corporate committee (Java's JCP, C++'s ISO committee). Both models have drawbacks. BDFLs create bottlenecks and succession crises. Committees move glacially and favor entrenched interests.

Rust needed something different. As a systems language targeting production use at companies like Mozilla, Microsoft, and Amazon, it required stability. But as an open-source project competing with decades-old alternatives, it needed to innovate rapidly. The RFC (Request for Comments) process, borrowed from Internet engineering standards (IETF RFCs), provided a middle path: structured community governance with clear decision-making authority. The rust-lang/rfcs repository implements this process, serving as both the proposal system and the permanent record of Rust's design decisions.

Technical Insight

Writes RFC using template

Submitted to repo

Reviewed by

Language changes

Library additions

Compiler changes

Enters

Enters

Enters

10 days review

Consensus reached

Not approved

RFC Document Structure

Motivation

Technical Specification

Drawbacks & Alternatives

Contributor

RFC Pull Request

Community Discussion

Sub-team Triage

Language Team

Library Team

Compiler Team

Final Comment Period

Decision

RFC Merged

RFC Closed

System architecture — auto-generated

The RFC process establishes clear thresholds for what requires formal review. Not every change needs an RFC—bug fixes, performance optimizations, and documentation improvements flow through normal GitHub PRs. RFCs are required for semantic or syntactic language changes, standard library additions, removing language features, and changes to the RFC process itself. This triage mechanism prevents governance overhead from strangling day-to-day development.

The lifecycle of an RFC follows a structured path. A contributor writes a proposal using the RFC template, submitting it as a pull request. The template itself is revealing—it requires sections on motivation, guide-level explanation, reference-level explanation, drawbacks, rationale and alternatives, prior art, unresolved questions, and future possibilities. This structure forces proposers to think holistically about their feature, not just advocate for it.

Here's what a minimal RFC structure looks like:

# RFC: Feature Name

## Summary
One paragraph explanation of the feature.

## Motivation
Why are we doing this? What use cases does it support?
What is the expected outcome?

## Guide-level explanation
Explain the proposal as if teaching it to a Rust programmer.
Introduce new named concepts and provide examples:

```rust
// Example of the proposed feature
fn example() -> Result<(), Error> {
    let data = some_new_feature()?;
    process(data)
}

Reference-level explanation

Technical details: syntax, semantics, interaction with other features.

Drawbacks

Why should we not do this?

Rationale and alternatives

  • Why is this design the best?
  • What other designs were considered?
  • What is the impact of not doing this?

Prior art

How do other languages handle this?

Unresolved questions

What parts need resolution during implementation?


Once submitted, the RFC enters a discussion phase. This is where the process shines—and where it can feel chaotic. Anyone can comment on the PR, leading to threads with hundreds of comments debating syntax choices, implementation complexity, and philosophical alignment with Rust's core values (memory safety without garbage collection, zero-cost abstractions, ergonomics). The sub-team responsible for that domain (lang, libs, compiler, cargo, etc.) monitors these discussions.

When a sub-team believes consensus has formed, they move the RFC into Final Comment Period (FCP), a 10-day window advertised in "This Week in Rust" and other channels. This is the last chance for the broader community to raise concerns. FCP ensures no silent decisions—every significant change gets visibility beyond GitHub subscribers. After FCP, the sub-team makes a final decision: merge (accepted), close (rejected), or postpone (not now, maybe later).

Merged RFCs become numbered documents in the repository, creating a permanent archive. RFC 2229 ("Closures capture individual fields") explains why closures became more ergonomic. RFC 3086 ("Reserved prefixes in the 2021 edition") documents forward compatibility strategy. This archive serves as institutional memory, letting future contributors understand not just what Rust does, but why.

The governance structure also reveals itself through directory organization. The `text/` directory contains accepted RFCs numbered sequentially. The pull requests themselves—both open and closed—represent active proposals and rejected ideas. Sub-teams have their own markdown files (`libs-rfcs.md`, `compiler-rfcs.md`) defining their specific processes. This transparency is radical: you can see exactly how decisions get made, who has authority, and what criteria they use.

## Gotcha

The RFC process optimizes for correctness and consensus, not speed. RFCs can sit for months without feedback if they don't align with current sub-team priorities or if the design space is unclear. There's no SLA, no guaranteed response time. For contributors excited about a feature, this feels like shouting into a void. The reality is that Rust's sub-teams are small, largely volunteer-based, and drowning in proposals. Your RFC might be excellent and still get no traction because the compiler team is focused on trait system improvements, not your syntax sugar idea.

The process also has hidden social barriers. Successful RFCs typically come from contributors who understand Rust's design philosophy, can anticipate implementation challenges, and engage constructively with criticism. The RFC template itself requires you to think like a language designer: considering alternatives, understanding prior art, articulating drawbacks. This filters for sophisticated proposals but potentially excludes valuable ideas from people who haven't internalized these norms. If you're new to Rust or language design, writing an RFC can feel like trying to argue a case before the Supreme Court when you just learned what laws are. The community is generally welcoming, but the bar for coherent, complete proposals is genuinely high.

## Verdict

Use if you're proposing substantial language changes, major library additions, or feature removals—basically anything that affects Rust's API surface or semantics. Also study this repository if you're designing a governance process for an open-source project, researching programming language evolution, or trying to understand why Rust made specific design choices. The archive is an incredible resource for seeing how technical communities resolve complex tradeoffs. Skip if you're contributing bug fixes, documentation, performance improvements, or minor API additions—those use normal GitHub workflows in the respective repos (rust-lang/rust, rust-lang/cargo). Also skip if you expect rapid feedback or are unwilling to engage in lengthy technical debates. The RFC process is democratic and thorough, which means it's also slow and demanding.
// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/rust-lang-rfcs.svg)](https://starlog.is/api/badge-click/developer-tools/rust-lang-rfcs)