Library / SDK
rust-lang/libc avatar
rust-lang/libc

libc publishes two release lines at once, and the manifest on the default branch is one alpha ahead of the registry

Raw bindings to platform APIs for Rust

2,648 stars1,342 forksRustApache-2.0

At a glance

What is it?
rust-lang/libc is raw FFI bindings to C-like platform libraries, and it is in the middle of its 1.0 transition: main carries 1.0.0-alpha.5 while the registry's newest alpha is alpha.4 and the newest stable is 0.2.190, with a second branch maintained for it. Its minimum Rust version is 1.65, with a policy for raising it still unfinished.
Who is it for?
Adopt libc for what it is, a target dependent table of C declarations that nothing else in the ecosystem maintains, and read the version you depend on as a decision rather than a detail. Three things to check.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • rust-lang/libc2,648 ★ · +28
Star history
Repository2026-09-292026-11-14
rust-lang/libc2.6k2.6k

28 Stars in the last 46 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Two release lines publish from one repository

The maintenance model is stated as two active branches: the default branch for the upcoming 1.0 release, and a second branch named for the currently published 0.2 line. Pull requests target the default branch by default and are cherry picked to the 0.2 branch when they need to be, which means every fix can land twice and the 0.2 line is the one most dependants actually resolve. The releases show both running at once. On 2026-07-21 the registry received 1.0.0-alpha.4 and, forty one minutes later, 0.2.189. The newest 0.2 release, 0.2.190, followed on 2026-10-02, and the last commit to the repository is dated 2026-10-02. The page also says new 0.2 releases stop once 1.0 is released, so this dual publishing is a closing phase rather than a permanent arrangement, and a project watching the 0.2 line needs to plan for the day it goes quiet.

The usage line says 0.2 while the default branch is already 1.0

The dependency you are told to add is short:

toml
[dependencies]
libc = "0.2"

Meanwhile the manifest on the default branch declares version 1.0.0-alpha.5, which is one alpha ahead of the newest alpha on the registry. So a reader who follows the documentation and a reader who browses the repository are looking at different versions of the same crate, and the difference is not cosmetic: the 0.2 line is the one with patch releases and cherry picked fixes, while the 1.0 line is where the structural work happens. Anyone considering the alpha should also notice what the manifest already contains, an edition setting of 2021, a minimum Rust version of 1.65 as a formal field, and an include list that decides what ends up in the published package. None of those is a reason to wait, and all of them are reasons to read the alpha's manifest rather than assume it matches the stable line.

The minimum Rust version can move without a breaking release

The stated minimum supported toolchain is Rust 1.65, and the manifest records the same number in its rust-version field, so the two agree today. What the page adds is that increases to that floor are allowed to ship without a major, semver breaking release, explicitly to avoid a ripple through the ecosystem, and that the policy for when such an increase may happen is a work in progress. That is an unusual thing to publish and it is worth reading twice: the floor is a moving target by design, and the conditions for moving it are not written down yet. The other half of the sentence is softer in the other direction: the crate may continue to compile with Rust versions older than the current floor, but that is not guaranteed. So both ends of the version range are soft, which is a deliberate trade for a crate this widely depended on.

Every item is at the crate root and matches the target

The design is flat and target dependent. All platform types, functions and constants are exported directly under the crate root, so every item is reachable as `libc::` followed by its C name, with no per module paths to remember. The three examples the page gives are a type, a constant and a function header, which is the whole surface in miniature. The important clause is the last one: the types and values of the exported APIs match the platform the crate is compiled for. A name that is a plain integer on one target can be a different width on another, and a constant can carry a different value, while your source stays identical. That is the reason this crate exists rather than a hand written list of extern declarations in your own crate, and it is also the reason a binding copied from a 64 bit target into a 32 bit one needs checking rather than trusting.

Windows is the platform this crate declines

One platform is called out by name as out of scope. Windows API bindings are not included here, and the page points at a separate crate for them. The reasoning follows from the design rather than from effort: what this crate provides is the C-like standard library surface of Unix-like systems, their types, their error constants and their function declarations, and the Windows equivalents are not that shape. So a program that targets both families carries two binding crates, and a reader who assumes one covers both will discover the gap at the import rather than at the documentation. The page also links the design RFC for anyone who wants the argument behind the flat crate root layout, which is the piece of this crate most likely to be argued about.

The documentation target list is kept in sync by hand

Platform support is expressed as two different things, and one of them needs a human. The published documentation for each target is generated from a target list in the manifest, and that list is grouped into tiers: Apple, Windows and Linux targets with host tools, a second tier one group without them, then a long tier two group covering loongarch64, riscv64gc, s390x, sparcv9 on Solaris, powerpc64 in several variants, arm and armv7 variants, and the illumos, FreeBSD and musl targets. A comment above the list says to keep it in sync with the verification script in the ci directory, which is the file that records the platforms each toolchain is guaranteed to build on. So the documentation matrix and the build guarantee are two hand-maintained lists pointing at each other, and the test matrices in the actions configuration are a third record of which targets are actually exercised. Nothing checks the three against each other automatically.

The published crate is a subset of the repository

The manifest's include list decides what a dependant receives, and it names the source directory, the tests, an examples path, the build script, the changelog, the license files and the readme. Everything else in the repository stays out of the package. That rules out the directory holding the test framework, the directory using that framework, the verification script the documentation points at, the ancillary directory, and the workflow configuration, which is sensible, since none of it is needed to compile against the platform. Two details are worth noting. The build script is included, so crate consumers do run it. And the examples path appears in the include list while no directory of that name appears among the repository's top level entries, which is what either an empty path or a leftover in the list would look like from the outside.

Three automation files from three different eras share one root

The root of the repository carries configuration for merging, releasing, triaging and formatting, and the dates those tools come from differ. A bors configuration is the merge bot that predates most current continuous integration setups. A release planner configuration sits beside it, which is what publishes the two version lines described earlier. A triage bot configuration handles incoming issues. There is a file listing revisions to be ignored by blame, which is the convention for the commits that reformat the whole tree at once, and separate formatting and editor configuration files beside it. None of this is unusual for a project of this age and size, and together it explains why the repository looks the way it does: a crate whose commits come from machines as well as people, where formatting churn is expected and therefore hidden from blame.

Editorial conclusion

Adopt libc for what it is, a target dependent table of C declarations that nothing else in the ecosystem maintains, and read the version you depend on as a decision rather than a detail. Three things to check. Decide deliberately between the 0.2 line everyone installs and the 1.0 alpha line, because the documentation still tells you to depend on 0.2 while the default branch is 1.0 work that will stop receiving fixes once 1.0 ships. Remember that a minimum Rust version can move without a breaking release, so a crate you depend on today can raise its floor later and leave your build behind. And keep Windows bindings out of your plan, since this crate declines that platform and points elsewhere. Anything beyond calling C functions is your own code, not this crate's.

Frequently asked questions

How do you add the libc crate to a Rust project?

Add libc = "0.2" under dependencies in Cargo.toml. The 1.0 line is still an alpha, the newest published stable is 0.2.190, and the manifest on the default branch is already at 1.0.0-alpha.5.

Does the libc crate include Windows API bindings?

No. Windows bindings are outside this crate's scope and the page points to the windows-sys crate for them. What libc exports is the C-like platform surface, with every item reachable under the crate root as libc::foo.

What is the minimum supported Rust version for libc?

Rust 1.65, stated as the minimum supported toolchain and recorded as the rust-version field in the manifest. Raises are allowed without a major release, and the policy for when that may change is described as a work in progress.

Which platforms does the libc crate support?

A script in the ci directory records the platforms guaranteed to build for each toolchain, and the actions matrices record where tests run. The manifest's documentation metadata lists target triples in tiered groups, from Apple and Windows tier one down to loongarch64, riscv64gc, s390x and sparcv9 targets.

Is libc 1.0 released yet?

No. The repository keeps two active branches, the default one for the upcoming 1.0 release and a second for the published 0.2 line, and states that new 0.2 releases stop once 1.0 is released. Both lines published on the same day in July 2026.

What license does the libc crate use?

Either, at your option: the Apache License version 2.0 or the MIT License, with both license files at the root of the repository. Contributions are dual licensed the same way unless a contributor states otherwise.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. rust-lang/libc on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rust-lang-libc.svg)](https://hysenlabs.com/projects/rust-lang-libc)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/rust-lang-libc.svg)](https://hysenlabs.com/projects/rust-lang-libc)

Was this useful?