A close up view of a machine with gears

The C to Rust Migration Book

By Mainmatter

You don't have to rewrite everything

Most Rust migration guides tell you to start fresh. That's not how it works in practice. Real codebases are large, deployed, and depended on. You need a strategy that lets C and Rust coexist while you migrate piece by piece.

That's what this guide covers. You'll learn how to bridge C and Rust through FFI, expose clean Rust APIs to existing C consumers, and progressively replace C with safe, idiomatic Rust, without breaking anything along the way.

Free course

The C to Rust Migration Book

Start the course
C to Rust migration books

Go through "The C to Rust Migration Book" and learn how to bridge C and Rust through FFI, one concept at a time. You'll learn how languages communicate at the binary level, how to make that boundary safe and maintainable, and how to expose clean Rust APIs to existing C consumers.

The guide assumes basic familiarity with both C and Rust. No prior FFI experience required; that's exactly what it teaches.

You'll build up your knowledge in small, manageable steps. By the end, you'll have the tools and confidence to introduce Rust into a production C codebase incrementally, without disrupting what's already working.

Get notified about new content

We're actively working on new chapters for The C to Rust Migration Book. Subscribe to get notified when new content is published.

Curriculum

1

Foreign Function Interfaces

We kick off with the fundamentals of FFI: how C and Rust communicate at the binary level through the C ABI, symbol tables, and the linker. You'll learn why C became the universal standard for language interoperability and write your first extern "C" blocks by hand. You'll understand exactly what you're promising the compiler when you declare a binding — and what happens when you get the signature wrong.

2

Types and Data Across the Boundary

This module covers how to safely move primitive values, strings, structs, and collections across the language boundary while preserving clear ownership semantics. You'll use bindgen to automate the generation of Rust bindings from C headers, and cbindgen to generate C headers from your Rust code, and learn how to configure both for a real codebase with non-trivial types.

3

FFI-Safe Types

Raw pointers and untyped primitives are the biggest source of bugs at the FFI boundary. This module introduces safer alternatives: NonNull, Option, newtype wrappers, and enum-based discriminants that carry meaning instead of just values. You'll learn to design types that make invalid states unrepresentable, even when talking to C code that has no type safety of its own.

4

Validation and Narrowing

Every FFI function is a trust boundary. C callers can pass null pointers, out-of-range values, or invalid UTF-8 — and Rust has no way to know at compile time. This module builds a discipline around validating and narrowing inputs at the boundary before they reach safe Rust, so that garbage data from C can never propagate into your business logic.

5

Error Handling and API Design

Rust's Result and ? stop at extern "C". This module covers how to convert Rust's error types into C-compatible results: error code enums, out-parameters, and how to surface meaningful failure information without leaking Rust internals. You'll also learn to expose coarse operations rather than fine-grained setters and keep your API surface intentionally small.

6

Production-Quality FFI

The final module ties everything together. You'll document FFI functions using Rust's /// # Safety convention with numbered invariants, so every unsafe contract is explicit and surfaces as C doc comments in the generated headers via cbindgen. We cover build integration, automated checks, and the mindset of treating your FFI surface as an API you'll maintain forever.

The author

Jonas Kruckenberg

Jonas Kruckenberg

    Senior Engineering Consultant @Mainmatter

    Jonas Kruckenberg is a systems engineer and technologist focused on next-generation computing infrastructure, including k23 - an experimental operating system. As a TC39 Invited Expert, he helps shape the future of web standards by bringing non-browser WebAssembly perspectives to language standardization.

    Need more than a guide?

    Mainmatter is a software consulting company that specializes in Rust. We offer consulting services, training, and mentorship to companies that want to migrate from C to Rust or introduce Rust into an existing codebase.

    Get in touch if you are working on a C to Rust migration and need hands-on support.

    Team Up With Us for Rust!
    EuroRust 2026 logo

    Community

    Meet other Rust enthusiasts at EuroRust

    Mainmatter organizes EuroRust, a two-day conference covering Rust patterns, systems programming, CLI tooling, servers, WebAssembly, and embedded systems. Join us in Barcelona in October 2026!

    Visit EuroRust