Back to Articles

Inside Rust's RFC Process: How a GitHub Repo Governs a Programming Language

[ View on GitHub ]

Inside Rust’s RFC Process: How a GitHub Repo Governs a Programming Language

Hook

Most languages evolve behind closed doors. Rust decided to make every design decision—from syntax changes to library additions—visible in GitHub pull requests that anyone can comment on.

Context

Programming language evolution typically happens in one of two ways: either a small group of core maintainers makes decisions privately, or chaos reigns as contributors push changes without coordination. Python has PEPs reviewed by a steering council. JavaScript has TC39 meetings with corporate representatives. But these processes often lack transparency or exclude community voices until it’s too late.

Rust chose a different path. The rust-lang/rfcs repository isn’t software—it’s a process encoded as a GitHub workflow. When you want to add new syntax, remove a language feature, or make a substantial change to the standard library, you don’t lobby maintainers privately. You write a markdown document, submit it as a pull request, and defend your proposal publicly. Every objection, every alternative considered, every compromise made gets archived forever in the PR thread. This repository is the legislative branch of Rust’s governance.

Technical Insight

Sub-teams

GitHub PR Workflow

Yes

No

Approved

Rejected

Defer

Contributor Copies Template

Draft RFC Markdown

Submit as GitHub PR

Sub-team Assignment & Labeling

Community Discussion

Needs Changes?

Final Comment Period

10 days minimum

Sub-team Sign-off?

Merge to Repository

Accepted RFC

Close PR

Rejected

Postponed Status

Permanent RFC Archive

System architecture — auto-generated

The RFC process uses GitHub’s pull request mechanism as a state machine for proposal evaluation. Here’s how it works architecturally: proposals start as markdown files copied from a template (0000-template.md), submitted as PRs to the rfcs repository. The README specifies a structured approach but doesn’t enumerate exact section requirements beyond emphasizing that RFCs should present convincing motivation and demonstrate understanding of design impact.

The workflow looks like this:

# Copy the template
cp 0000-template.md text/0000-my-feature.md

# Fill in the RFC following the template structure
# (specific sections are defined in the template file)

# Submit as PR, then rename file with PR number
mv text/0000-my-feature.md text/1234-my-feature.md

Once submitted, the RFC enters a multi-stage review pipeline. First, it gets labeled and assigned to a relevant sub-team (language, library, or compiler). Each sub-team has specific guidelines—language changes require RFCs for any semantic or syntactic modifications, library changes need RFCs for large standard library additions (though minor ones use the lighter-weight ACP process referenced in the README), and compiler changes have their own specific guidelines linked from the main README.

The critical governance innovation is the Final Comment Period (FCP). When a sub-team believes an RFC is ready for decision, they initiate FCP—a mandatory ten calendar day period (open for at least 5 business days) that broadcasts intent to merge, postpone, or close. This prevents surprise decisions on controversial proposals. FCP requires explicit sign-off from all members of the relevant sub-team, creating a paper trail of who endorsed what.

Consensus-building happens entirely in PR comment threads. The README explicitly states: “The sub-team will discuss the RFC pull request, as much as possible in the comment thread of the pull request itself. Offline discussion will be summarized on the pull request comment thread.” This radical transparency means you can read the exact arguments that convinced the Rust team to add features or make changes.

The repository structure is minimal by design—just markdown files in a text/ directory, organized by RFC number. Accepted RFCs become permanent documentation of design rationale. When future developers ask “why does Rust work this way?”, they can trace back to the original RFC and read the complete decision-making context. This architectural choice—using PRs as the workflow engine rather than building custom tooling—means the process is accessible to anyone familiar with GitHub, lowering barriers to participation.

Gotcha

The RFC process trades speed for thoughtfulness, and that trade-off can be challenging for controversial proposals. The README acknowledges that “RFCs rarely go through this process unchanged” and emphasizes building consensus, noting that “RFCs that have broad support are much more likely to make progress than those that don’t receive any comments.”

The process also has a learning curve for newcomers. The README explicitly recommends “feedback from other project developers beforehand” and mentions pursuing discussion on Zulip or the developer forum before submitting, noting that “A hastily-proposed RFC can hurt its chances of acceptance” and that “Low quality proposals, proposals for previously-rejected features, or those that don’t fit into the near-term roadmap, may be quickly rejected.” In practice, this means you need to do invisible pre-work—building consensus informally—before the formal process even starts. The README warns: “If you submit a pull request to implement a new feature without going through the RFC process, it may be closed with a polite request to submit an RFC first.”

Finally, the repository provides minimal tooling beyond the basic GitHub PR interface. The README mentions rfcbot.rs for viewing active RFCs and links to the RFC Book, but there’s no built-in automation for format validation or workflow tracking. You’re working with raw markdown files and GitHub’s standard features.

Verdict

Use if you’re proposing semantic or syntactic changes to Rust, removing language features (including feature-gated ones), or adding large components to std—these changes are mandatory RFC territory per the README. Also use this process if you value transparent governance and want a permanent public record of design decisions. The process excels when you need broad stakeholder input and can invest time in consensus-building. Skip if you’re fixing bugs, improving documentation, making changes that “strictly improve objective, numerical quality criteria (warning removal, speedup, better platform coverage, more parallelism, trap more errors, etc.)”, or making additions “only likely to be noticed by other developers-of-rust, invisible to users-of-rust”—these explicitly don’t require RFCs per the README. For minor standard library additions, the README directs you to use ACPs instead as referenced in the std-dev-guide.

// 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)