Open-source project
gulrak/filesystem avatar
gulrak/filesystem

gulrak/filesystem: Portable C++11 Filesystem

An implementation of C++17 std::filesystem for C++11 /C++14/C++17/C++20 on Windows, macOS, Linux and FreeBSD.

1,573 stars205 forksC++MIT

At a glance

What is it?
gulrak/filesystem is a header-only implementation of the C++17 filesystem interface for C++11 through C++20. It is useful when a project needs portable path and directory operations but cannot depend on a standard library that provides `std::filesystem`.
Who is it for?
Adopt gulrak/filesystem for legacy C++11 or C++14 applications, portable libraries that need one filesystem implementation across supported operating systems, or code that must remain compatible with older compilers. Do not add it when the project already requires C++17 or C++20 and a conforming `std::filesystem` is available, unless the documented exceptions are acceptable.
Can I use it commercially?
Yes. MIT 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 40 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

Why gulrak/filesystem Exists for Pre-C++17 Code

gulrak/filesystem addresses a practical language-version gap. Applications written for C++11 or C++14 do not have the C++17 filesystem library, yet they still need path manipulation, directory enumeration, file existence checks and related operations. Pulling in several small platform-specific libraries can complicate a codebase, particularly when the same application must compile on Windows, macOS, Linux and FreeBSD.

The project provides that functionality in the `ghc::filesystem` namespace. Its interface is based on C++17 and C++20, while its implementation can be compiled as C++11, C++14, C++17 or C++20. This makes it most relevant to libraries that still need older language-mode support and to applications being migrated incrementally. The README presents it as an almost drop-in compatibility layer, not as an attempt to replace `std::filesystem` when the standard library already supplies it.

The namespace choice has a practical purpose. In a mixed environment where some translation units expose `std::filesystem`, compiling against `ghc::filesystem` avoids requiring the project to standardize every caller on the standard-library namespace. It does, however, mean that source code using the library is not literally interchangeable with `std::filesystem` without changing namespaces and checking the documented exceptions.

Single-Header Architecture and Filesystem Data Flow

The central design choice is a header-only, single-file library. No separately compiled runtime library is described. Consumers obtain the header, expose its `include` path to the compiler and compile filesystem operations directly into each translation unit that uses them. This fits the project's motivation of reducing dependencies in older C++ code, although it does not guarantee identical binary size across all translation units because each including translation unit sees the implementation.

The API follows the filesystem model associated with C++17 chapter 30.10. Its main abstraction is the path object, used to construct, inspect and transform filesystem paths. The project also implements directory access and associated filesystem operations. Callers work with `ghc::filesystem` types and functions instead of the equivalent `std::filesystem` entities.

Platform behavior is implemented underneath this common interface. Windows receives its own filesystem treatment, while macOS, Linux and FreeBSD use the POSIX side of the project. The repository contains CMake project files, an `examples` directory, an `include` directory and a `test` directory. Unit tests are registered with CMake and use Catch2, which indicates that the library has a repository-level test suite rather than only documentation examples.

This architecture is suitable for source distributions and cross-platform libraries. It also means the header must compile under every language mode claimed by the project, including older GCC and Clang combinations listed in the CI matrix. Consumers should treat compiler and language-version compatibility as part of integration rather than assuming that a modern compiler test is sufficient.

Download and First Filesystem Use

The README directs users to its Downloads, “Using it as Single-File-Header,” “Using it as Forwarding-/Implementation-Header,” and “Git Submodule and CMake” sections. The README does not include an exact download command, header path, CMake option or compiler command, so this review does not invent them. Obtain the library from the project repository and follow the relevant README subsection for the integration model required by the build system.

For a first real use, select a source file that needs portable path handling and include the `ghc` filesystem interface. The operation to exercise should be `ghc::filesystem::path` work, since the maintainer's motivation specifically mentions path use and the project description confirms support for path and directory functionality. Existing calls written against `std::filesystem` can then be evaluated as possible namespace substitutions, but they must be checked against the README's API and behavior differences before migration.

The repository also contains `examples/dir.cpp` and `examples/du.cpp`, with registration through `examples/CMakeLists.txt`. These are the most relevant files to inspect for concrete directory-oriented use. The README does not reproduce their source contents, so this review cannot quote or verify their exact APIs. Similarly, no executable smoke test or build result is claimed here.

A sound first integration step is source-based rather than speculative: confirm the official header name from the checked-out README, compile the repository examples through its documented CMake setup, and compare the resulting path or directory behavior with the target application. That also verifies that the selected compiler mode is accepted by the header.

Cross-Platform Coverage and UTF-8 Constraints

The continuously tested CI matrix is broader than the basic platform list. It covers macOS 14 and 15 on Apple Silicon, several Visual Studio toolchains, MSYS2 configurations, Ubuntu 22.04 and 24.04, older GCC and Clang Docker builds, Rocky Linux, and FreeBSD 14. Modern CI jobs exercise C++11, C++17 and C++20 where the toolchains support them. This is useful evidence that the project is not limited to one operating-system API or one compiler family.

There is still a clear boundary between continuously tested and reported platforms. The README says the library has been reported to work on Android, iOS, Emscripten, QNX, GNU/Hurd, Haiku and Solaris, but those systems are not in the continuous automated matrix. A project targeting one of them should not treat the compatibility claim as equivalent to ongoing regression coverage.

The most consequential documented constraint is the library's “UTF-8 Everywhere” policy. The README states that every `std::string` is interpreted as UTF-8 for encoding purposes, while `std::u16string` is treated as UTF-16. Applications that carry legacy local byte strings, mixed encodings or platform-specific assumptions should review this behavior before adopting the header. The author also identifies UTF-8 preference as an exception to the otherwise drop-in positioning.

The README separately lists LWG defects, behavior not implemented before C++17, API differences and Windows symbolic-link and permission issues under Open Issues. It does not provide enough detail here to characterize each defect or Windows issue. Code migration must consult those sections rather than assuming textual substitution.

gulrak/filesystem Versus the Standard std::filesystem

The closest alternative is the compiler's own `std::filesystem` when building with C++17 or C++20. The implementation approach differs in ownership of behavior. `std::filesystem` is part of the standard library supplied by the toolchain, whereas gulrak/filesystem supplies a compatibility implementation in the `ghc::filesystem` namespace for language modes that lack the standard facility.

The standard library is the better fit when the project already requires C++17 or C++20 and its supported compiler versions provide a satisfactory implementation. It avoids a separate compatibility layer and does not require source migration from `std::filesystem` to another namespace. The README itself does not claim that gulrak/filesystem is a better implementation.

gulrak/filesystem is the better fit when the same codebase must compile as C++11 or C++14, support older compiler generations, or share one filesystem abstraction across mixed language modes. Its header-only distribution also fits projects that prefer source-level integration. The trade-off is that adopters must accept the UTF-8 Everywhere model, review the documented deviations and keep the header's supported compiler and platform matrix aligned with their own.

Maintenance Signals and Adoption Cost

The repository is not archived. Its last push was on 2026-09-14, and the listed release v1.5.16 dates from 2026-07-19. Those facts indicate recent repository and release activity, but they do not by themselves guarantee compatibility with every platform. The project publishes version-specific release tags and documents behavioral differences, so upgrades should account for changes between versions rather than copying the newest header without review.

The library is distributed under the MIT License. That permits use, modification and distribution under the license's stated conditions, including preservation of its copyright and permission notice. This is a license summary, not legal advice. Because the implementation is header-only, adoption also creates a maintenance obligation to monitor its compiler compatibility and vendor or update the header with the consuming project.

The practical upgrade cost is concentrated in source compatibility and validation. Migration touches include directives, namespace names, string encoding assumptions, exception handling and any filesystem operation affected by the documented API or behavior differences. Consumers also need their own build coverage for the platforms they ship. The repository's Catch2 suite can help during integration, but the application still has to verify its path data, permissions, symbolic-link expectations and target filesystem layout.

Editorial conclusion

Adopt gulrak/filesystem for legacy C++11 or C++14 applications, portable libraries that need one filesystem implementation across supported operating systems, or code that must remain compatible with older compilers. Do not add it when the project already requires C++17 or C++20 and a conforming `std::filesystem` is available, unless the documented exceptions are acceptable. Verify first that the compiler, platform, encoding assumptions and behavioral differences match the application.

Frequently asked questions

Does gulrak/filesystem support C++11 and C++14?

Yes. The project implements a C++17 and C++20-compatible filesystem interface for C++11, C++14, C++17 and C++20.

Is gulrak/filesystem a separate compiled library?

No. It is described as a header-only, single-file library, so the implementation is used by including its header rather than linking a separately compiled runtime library.

Should gulrak/filesystem replace std::filesystem in a C++17 project?

The README says it is not intended to replace `std::filesystem` where a full C++17 or C++20 implementation is available. It is mainly an almost drop-in option for projects that cannot use the standard facility.

Which platforms are continuously tested?

The documented CI matrix covers macOS, Windows, Ubuntu, Rocky Linux and FreeBSD with listed compiler toolchains. Other platforms have been reported to work, but the README says they lack continuous CI coverage.

Official sources

  1. gulrak/filesystem on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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/gulrak-filesystem.svg)](https://hysenlabs.com/projects/gulrak-filesystem)

Was this useful?