Rust: write one code for Windows, macOS and Linux without pain

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why is Rust an ideal candidate for cross-platform development?

\n

In the world of software development, there is an eternal pain: write a program once and run it on Windows, macOS, and Linux. Usually, this turns into a nightmare with conditional directives, dancing around file paths, and endless testing. But there is a language that solves this problem at the system level — Rust.

\n

Rust was designed with cross-platform capabilities in mind. Its compiler (rustc) can generate binaries for dozens of architectures and OSes. But the main thing is that the standard library (std) already includes an abstraction over the operating system. You write code, and Rust itself handles how to work with files, threads, or networking on a specific platform. This is not magic, it's good design.

\n

In this article, we will not just talk about theory. We will break down real code examples: from a simple "Hello, World!" to working with the file system and creating a GUI application. You will see how cross-platform development in Rust turns from a headache into a pleasure. Let's go!

\n\n

How does Rust ensure cross-platform compatibility?

\n

Rust's secret lies in its three-level abstraction system:

\n
    \n
  • Platform-independent code — 90% of your program. Uses only std, works identically everywhere.
  • \n
  • Conditional compilation — for platform-dependent pieces. Rust allows you to include or exclude code depending on the target OS.
  • \n
  • External crates — libraries like serde or tokio that already solve cross-platform problems for you.
  • \n
\n

The basic principle: you write common code, and for rare exceptions, you use the #[cfg(target_os = "...")] directives. This is cleaner than in C/C++, where you often have to build entire blocks of #ifdef.

\n\n

Example: determining the platform in code

\n

Let's see how to find out which OS the program is running on, without dirty hacks:

\n
fn main() {\n    if cfg!(target_os = "windows") {\n        println!("Running on Windows");\n    } else if cfg!(target_os = "macos") {\n        println!("Running on macOS");\n    } else if cfg!(target_os = "linux") {\n        println!("Running on Linux");\n    } else {\n        println!("Unknown OS (but Rust still works!)");\n    }\n}\n
\n

Important: cfg! is a macro that is evaluated at compile time. If you compile this code on Linux, only the Linux branch will end up in the binary. No extra code — no problems.

\n\n

Working with the file system: write once

\n

A classic headache — file paths. On Windows it's C:\\Users\\name\\file.txt, on Linux it's /home/name/file.txt. Rust solves this through the Path trait and the PathBuf struct.

\n

Let's look at an example: creating a directory and writing to a file. The code will work on any OS without changes:

\n
use std::fs;\nuse std::path::PathBuf;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    // Build the path to the user's home directory\n    let home = dirs::home_dir().expect("Failed to get home directory");\n    let mut path = PathBuf::from(home);\n    path.push("my_rust_app");\n    path.push("data");\n    \n    // Create the directory (recursively)\n    fs::create_dir_all(&path)?;\n    \n    // Create the file\n    let file_path = path.join("output.txt");\n    fs::write(&file_path, "Hello, cross-platform world!")?;\n    \n    println!("File saved: {:?}", file_path);\n    Ok(())\n}\n
\n

Here we used the dirs crate, which provides cross-platform access to system paths (home folder, AppData, etc.). Without it, we would have to write conditional compilation for each OS.

\n\n

Networking and working with threads

\n

The Rust standard library provides a unified API

Blogs

Book Recommendations