Library / SDK
rust-windowing/winit avatar
rust-windowing/winit

winit: the Rust windowing layer that sits under everything else

Window handling library in pure Rust

6,181 stars1,358 forksRustApache-2.0

At a glance

What is it?
winit creates windows and delivers their events on Windows, macOS, Linux, Android, iOS and the web, but it draws nothing. Here is what that split means for a project, and where the 0.31 beta line stands.
Who is it for?
winit is the right dependency when you are building a toolkit, a renderer or a game engine and need one event loop that behaves the same on Windows, macOS, X11, Wayland, Android, iOS and the web. It is the wrong dependency if you want a button on screen today: winit has no widgets and no drawing, and the README says so directly.
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 last received commits 6 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

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

Editorial analysis

What winit actually owns, and what it hands back to you

winit is a window creation and management library. The README describes it as "a low-level brick in a hierarchy of libraries" and states that to show something on a window you need the platform-specific getters it provides, or another library. That sentence is the whole design contract. winit opens a native window, runs the platform event loop, and translates resizes, key presses, mouse movement and similar input into a single Rust event type. It stops before pixels.

The audience follows from that. If you are writing a GUI toolkit, a renderer, or a game engine that needs one event loop across desktop and mobile, winit is the layer you build on. If you want a window with a menu bar and a text field, winit gives you the window and nothing inside it. The README points readers looking for features outside its scope at the Are we GUI Yet? and Are we game yet? lists rather than pretending to cover them.

One facade crate over ten backend crates

The workspace layout is the clearest statement of how winit works. Alongside the `winit` facade there are `winit-android`, `winit-appkit`, `winit-common`, `winit-core`, `winit-orbital`, `winit-uikit`, `winit-wayland`, `winit-web`, `winit-win32` and `winit-x11`. Each backend crate is versioned in lockstep with the facade and pinned with an exact `=` requirement in the workspace manifest, so a backend cannot drift from the version of `winit` it was built against.

The data flow is a fan-in. Platform APIs produce events, the backend crate normalises them, and the facade exposes one event loop plus a per-platform module for the parts that cannot be normalised. Two dependency choices in the workspace manifest hint at the intended shape of that boundary: `raw-window-handle` 0.6 is pulled in with the `rwh_06` alias, which is how a renderer gets a native window handle out of winit, and `tracing` is a core dependency, so backends emit structured logs rather than printing. The `dpi` crate is a workspace member too, and the README notes that the repository `LICENSE` does not apply in full to it: full details are in that folder's README. That is worth reading before you vendor anything.

Adding winit and opening a first window

The README gives the dependency line directly. The version it shows is the current beta, so a project that needs the stable line should check crates.io for the latest 0.30 release instead.

toml
[dependencies]
winit = "0.31.0-beta.3"

From there the shape of a program is fixed by the library: you build an event loop, create a window from it, and run the loop, matching on events. The README does not walk through a full example, but it does point at two places that do. The repository has an `examples` directory at the top level, and the crate documentation lives at docs.rs/winit. There is also an unstable documentation build published from the master branch, linked from the README badge as UNSTABLE docs, which is where to look when you are tracking the beta rather than the release.

One version constraint matters before any of this compiles. The MSRV is Rust 1.86, stated in the README and repeated as `rust-version` in the workspace manifest. The README adds that a change to the MSRV comes with a minor version bump, and that the upper bound is tentatively `min(sid, stable - 3)`, where `sid` is the rustc shipped by Debian Sid. Two exceptions are named: Android may need a newer compiler for certain features, capped at stable minus three, and that restriction is not visible in Cargo metadata; Redox OS is outside the policy entirely and needs a nightly toolchain.

Where winit stops being the right tool

The absence of drawing is the obvious boundary, and winit states it rather than leaving it to be discovered. A window with no renderer is a blank rectangle. You supply the renderer, and you reach the native surface through the platform-specific getters or through `raw-window-handle`.

The less obvious boundary is the beta. The most recent release in the repository is v0.31.0-beta.3, published on 2026-09-04, and the workspace manifest carries `version = "0.31.0-beta.3"` with `edition = "2024"`. The last stable release is v0.30.13 from 2026-03-02. A project that cannot absorb API churn should read the beta as a preview of where 0.31 is going, not as a drop-in. The README does not document a rollback path between the two lines, so the migration story is whatever the changelog says.

Platform coverage has its own gaps. Orbital and the web backend exist as crates, but the README's MSRV section singles out Redox OS as requiring nightly, which is a real constraint if that target is on your list. And the repository-level licence note about the `dpi` folder means the Apache-2.0 identifier on the crate does not automatically describe every file in the tree.

winit against SDL2 and GLFW

The closest alternatives are SDL2 and GLFW, and the difference is not feature count. Both of those libraries bundle more than windowing: SDL2 ships audio, input device handling and a rendering API, and GLFW is C with a C API surface. They are C libraries that Rust code calls into, which means a build that depends on a C toolchain and, for SDL2, on system libraries being present.

winit is pure Rust, per the project description, and the workspace is all Rust crates. That changes what a build requires and what a cross-compile to Android or the web looks like. The trade is scope. Choosing winit means accepting that audio, rendering and widget code are separate decisions you make yourself, and that the platform-specific getters are part of your code rather than hidden behind a portable C API. If you want one dependency that does windowing and input and playback, SDL2 is the shorter path. If you want a Rust-native event loop with per-platform escape hatches, winit is the narrower and more honest fit.

Maintenance, the 0.31 beta line, and licence scope

The repository is not archived and the last push was on 2026-09-19, three days before this writing, so development is ongoing. The maintainers hold a meeting every Friday at UTC 15, with notes published on HackMD, and there is a Matrix room linked from the README. Those are the channels where a breaking change in the beta would be discussed first.

Upgrade cost comes from two places. The first is the MSRV policy: the floor moves with Debian Sid and stable Rust, and the README commits to a minor version bump when it does, so a toolchain upgrade can be forced by a routine dependency bump. The second is the beta itself. The exact `=` pins between the facade and the backend crates mean you upgrade the whole set together, and the `edition = "2024"` setting in the workspace manifest means the source assumes a recent compiler.

On licensing, the crate is Apache-2.0 and the workspace manifest sets `license = "Apache-2.0"` for every member. The README adds a caveat that the license in `LICENSE` does not apply in full to the `dpi` package and directs readers to that folder's README. Treat that as a file to read during dependency review rather than an assumption to carry over from the crate metadata.

Editorial conclusion

winit is the right dependency when you are building a toolkit, a renderer or a game engine and need one event loop that behaves the same on Windows, macOS, X11, Wayland, Android, iOS and the web. It is the wrong dependency if you want a button on screen today: winit has no widgets and no drawing, and the README says so directly. Before committing, check whether you can pin to the stable 0.30 line or need something from the 0.31 beta, confirm your toolchain meets the Rust 1.86 MSRV, and read the per-platform module docs for the backends you actually ship on, since that is where the platform-specific getters live.

Frequently asked questions

What is winit?

winit is a cross-platform window creation and management library written in pure Rust. It creates windows and lets you handle events such as resizes, key presses and mouse movement, but it does not draw anything itself.

How do you use winit in a Rust project?

Add it as a dependency, build an event loop, create a window from that loop, and run the loop while matching on the events it produces. The README points to the examples directory in the repository and to docs.rs/winit for the full API.

Which Rust version does winit require?

The MSRV is 1.86, stated in the README and as rust-version in the workspace manifest. Android may require a newer compiler for certain features, and Redox OS needs a nightly toolchain.

Does winit render anything to the window?

No. The README describes winit as a low-level brick and says that to show something on the window you need the platform-specific getters it provides, or another library.

Is winit actively maintained?

The repository is not archived and the last push was on 2026-09-19. The maintainers also hold a meeting every Friday at UTC 15 and publish the notes.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. rust-windowing/winit 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-windowing-winit.svg)](https://hysenlabs.com/projects/rust-windowing-winit)