PAL is a lightweight, low-level, cross-platform abstraction layer in C, designed to be explicit and as close to the OS as possible — similar in philosophy to Vulkan. It gives you precise control without hidden behavior, making it ideal for developers who want performance and predictability.
Originally named as Platform Abstraction Layer, PAL has evolved into Prime Abstraction Layer — the first and most direct layer between your engine or software and the operating system.
PAL is transparent. All queries — window size, position, monitor info, and more — reflect the current platform state. Using PAL is like working directly with the OS: it applies no hidden logic, makes no assumptions, and leaves behavior fully in your control.
This approach gives you total control: you handle events, manage resources, and cache state explicitly. PAL provides the building blocks; how you use them — whether for simple applications or advanced frameworks — is entirely up to you.
Example – Get Window Size
// Direct query from the platform — not cached by PAL
palGetWindowSize(window, &w, &h);Note: palGetWindowSize queries the OS directly. If your application needs continuous updates (e.g., window moves or resizes frequently), it is more efficient to listen to PAL events rather than repeatedly querying the OS. This ensures your app stays performant.
While libraries like SDL or GLFW focus on simplifying development through high-level abstractions. PAL is different:
- ✅ Explicit: You decide how memory, events, and handles are managed.
- ✅ Low Overhead: PAL is close to raw OS calls, ensuring performance.
- ✅ Modular: Pick only the subsystems you need (video, event, threading, OpenGL, etc.).
- ✅ Extendable: Plug in your own backends (event queue, allocator, etc.).
- ✅ Transparent: Exposes raw OS handles when you need them.
Here’s the smallest program that opens a PAL window:
#include "pal/pal_video.h"
int main() {
PalEventDriver* driver = nullptr;
PalEventDriverCreateInfo info = {0};
palCreateEventDriver(&info, &driver);
palInitVideo(nullptr, driver);
PalWindow* window = nullptr;
PalWindowCreateInfo w = {0};
w.width = 640;
w.height = 480;
w.title = "Hello PAL";
w.show = true;
palCreateWindow(&w, &window);
while (1) {
palUpdateVideo();
PalEvent e;
while (palPollEvent(driver, &e)) {
if (e.type == PAL_EVENT_WINDOW_CLOSE) return 0;
}
}
}➡️ Build and run this, and you’ll get a cross-platform window managed entirely by PAL.
For more detailed examples, see the tests folder tests folder, which contains full usage scenarios and validation cases.
- PAL is a thin layer over the OS, not a framework or library.
- Queries return the current platform state, reflecting any changes made through direct OS calls.
- Developers are responsible for state tracking, caching, and event handling.
- PAL enables cross-platform consistency while preserving full OS behavior and control.
- Advanced users can build libraries or frameworks on top of PAL.
- Minimal overhead (close to raw OS calls)
- Explicit API (no hidden behavior or defaults)
- Event system supporting both polling and callbacks
- Written in C for easy integration
- Stateless: Opaque handles, no internal caching
- No lowest common denominator: exposes platform capabilities directly
- Modular builds: include only the subsystems you need
- Windows (Vista+)
- Linux (X11)
- Linux (Wayland)
- macOS (Cocoa)
- Android
- iOS
- Standard C library
- Platform SDKs (Win32, X11, Cocoa, etc.)
- Make for Windows (if not using Visual Studio)
- XRandR (1.2+) for X11
- libXcursor for X11
- GCC
- Clang
- MSVC
PAL is written in C99 and uses Premake as its build system. Configure modules via pal_config.lua.
See pal_config.h to see the reflection of modules that will be built.
Windows
premake\premake5.exe gmake2 # generate Makefiles (default: GCC)
premake\premake5.exe gmake2 --compiler=clang
premake\premake5.exe vs2022 # generate Visual Studio project (default: MSVC)
premake\premake5.exe vs2022 --compiler=clangLinux
./premake/premake5 gmake # generate Makefiles (default: GCC)Enable tests in pal_config.lua by setting PAL_BUILD_TESTS = true.
pal_core- memory, log, time, versionpal_video- windows, monitors, mouse, keyboardpal_event- event queue, event callbackpal_thread- threads, synchronizationpal_opengl- framebuffer configs, context
pal_graphics- Vulkan, D3D12, Metal, Custompal_networkpal_audiopal_hidpal_filesystem
PAL uses Doxygen for generating API documentation.
cd docs
doxygen doxyfileThe generated HTML docs will be available in docs/html/.
Contributions are welcome! Please open an issue or pull request.
PAL is released under the Zlib License.