sokol-samples shows what a small C graphics stack looks like across five backends
Sample code for https://github.com/floooh/sokol
At a glance
- What is it?
- sokol-samples is the sample code for the sokol library, covering D3D11, GLFW, HTML5, Metal and the sokol-app harness with live WebGL2 and WebGPU demos. Its most useful feature is the fibs meta build system, which turns a multi-backend C project into one set of commands, and its manual build instructions show how little machinery a sample actually needs.
- Who is it for?
- sokol-samples fits a developer evaluating the sokol library who wants to see a working example per backend before reading the headers, and it fits anyone assembling a small C graphics application who wants one build system across native, web, iOS and Android.
- 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 3 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One library, nine backends, one directory per backend
sokol-samples is sample code for the sokol project, and the repository layout is a directory per graphics backend.
The top level entries are d3d11 for Direct3D 11, glfw for the GLFW windowing library, html5 for the browser target, metal for Apple Metal, and sapp for the sokol-app harness. There is also a libs directory, a webpage directory, and the build machinery itself: fibs, fibs.ts, fibs.cmd and fibs-scripts.
That structure is the point of the repository. A graphics abstraction is easy to describe and hard to believe until you see the same triangle running through five different APIs. The sokol-app samples are the ones with the most complete feature set, since that harness provides the windowing, input and audio plumbing, and the backend-specific samples exist to show the same work without it.
There are two live WASM demos linked from the README, one for WebGL2 and one for WebGPU, both hosted on GitHub pages. That is a faster way to judge the library than reading a README, and it also tells you the WebGPU path is exercised rather than aspirational.
The primary language is C, the licence is MIT with a LICENSE file at the root, there are no GitHub releases, and the last push to the repository was on 2026-10-20.
fibs is the actual interface
The build is driven by a tool called fibs, which the README describes as a meta build system with its own documentation at the floooh/fibs repository.
The whole flow is three commands. Clone, change directory, build.
git clone https://github.com/floooh/sokol-samples
cd sokol-samples
./fibs buildThat builds the samples in the host platform's default release mode configuration. Then you list the executables and run one.
./fibs list targets --exe./fibs run triangle-sapp-uiYou can also pick a specific configuration rather than accepting the default, and list the configurations that exist.
./fibs config [build-config-name]./fibs list configsBecause there are many configurations, the README suggests grepping the list, with grep or rg.
./fibs list configs | grep d3d11
./fibs list configs | rg macosThe configuration names are descriptive, and reading them tells you the matrix the project covers. The examples in the README include sapp-metal-macos-vscode-debug, sapp-gles-emsc-ninja-debug, sapp-metal-ios-xcode-debug and sapp-gles-android-ninja-debug. A name encodes the harness, the graphics API, the platform, the build tool, the generator and the configuration, which is how a project like this stays navigable.
Opening a sample in an IDE is two steps, and the first one is the configuration.
./fibs config sapp-metal-macos-vscode-debug
./fibs openThat works when the configuration name contains -vstudio-, -vscode- or -xcode-, and it means you can pick your editor and have the sample project opened in it.
Cross-compiling to Emscripten, iOS and Android
The three cross-compilation targets each have a short, specific recipe.
For Emscripten, install the SDK first, which the README warns will take a while.
./fibs emsdk installThen choose a configuration with -emsc- in the name, build and run.
./fibs config sapp-gles-emsc-ninja-debug
./fibs build
./fibs run triangle-sappRunning it opens the system default web browser running the selected sample.
For iOS, pick a configuration and open it in Xcode.
./fibs config sapp-metal-ios-xcode-debug
./fibs openThen you build and run in the iOS simulator or on an iOS device. For a real device you may need to provide an iOS Team Id, which you set with the set command.
./fibs set iosteamid [your-team-id]
./fibs config sapp-metal-ios-xcode-debugFor Android, install a JDK version 17 and check whether fibs can find java, javac and unzip, using the diag command.
./fibs diag toolsThe output shown in the README lists java, unzip and cwebp as found. Then install the Android SDK and NDK.
./fibs android installThen pick a configuration and build, and run any sample on an attached device.
./fibs config sapp-gles-android-ninja-debug
./fibs build./fibs run triangle-sappThe diag tools check is a good habit here. A missing JDK or unzip surfaces as a configuration problem rather than a mysterious failure later in the Android build.
Linking a local sokol checkout for development
If you are working on the sokol library itself, or on the samples, you need the samples to use your local sokol rather than the pinned imported version.
The README describes cloning sokol into a sister directory of sokol-samples.
git clone https://github.com/floooh/sokol ../sokolThen link the cloned directory to the sokol import.
./fibs link sokol ../sokolAnd verify with the list imports command, whose output shows the link target.
./fibs list importsAfter that, the sokol-samples project uses the linked sokol repository instead of the local imported version in the .fibs/imports subdirectory.
That import mechanism is worth understanding even if you never write a line of sokol. The samples are pinned to a specific sokol revision so that a sample stays reproducible, and the link command is the escape hatch for the one case where you need to change that revision, which is when you are changing it yourself.
The fibs tool also handles the toolchain installation for cross targets, since the emsdk and android install commands are fibs subcommands rather than separate setup scripts. That is a coherent design: one tool owns the whole matrix of targets rather than asking you to assemble a per-target toolchain by hand.
The manual build path is where the sample count stops mattering
The section on building without a build system is the most instructive part of the README, and it exists for a specific reason: it shows how little a sokol sample actually needs.
The expected directory layout for a manual build is three directories side by side.
sokol-samples
sokol
sokol-tools-binAnd the README shows how to create it.
> mkdir scratch
> cd scratch
> git clone https://github.com/floooh/sokol-samples
> git clone https://github.com/floooh/sokol
> git clone https://github.com/floooh/sokol-tools-binThen the compiler invocations. A Metal sample on macOS with clang is one command.
> cd sokol-samples/metal
> cc cube-metal.c osxentry.m sokol_gfx.m -o cube-metal -fobjc-arc -I../../sokol -framework Metal -framework AppKit -framework QuartzCoreA GLFW sample links against a system-wide glfw install.
> cd sokol-samples/glfw
> cc cube-glfw.c flextgl/flextGL.c -o cube-glfw -I../../sokol -lglfw -framework OpenGL -framework AppKitThe sokol-app samples show the two-step pattern of compiling the shader first with the prebuilt sokol-shdc tool, then compiling the program.
> cd sokol-samples/sapp
> ../../sokol-tools-bin/bin/osx/sokol-shdc -i cube-sapp.glsl -o cube-sapp.glsl.h -l metal_macos
> cc cube-sapp.c ../libs/sokol/sokol.m -o cube-sapp -DSOKOL_METAL -fobjc-arc -I../../sokol -I ../libs -framework Metal -framework AppKit -framework QuartzCore -framework AudioToolboxAnd the Windows path is a cl invocation from a Visual Studio command prompt.
> cd sokol-samples\d3d11
> cl cube-d3d11.c d3d11entry.c /I..\..\sokolThe README notes that you can put the sokol headers wherever you want, copying them into your own source directory, and that you do not have to use the prebuilt shader compiler. It also says many samples are simple enough to be built directly on the command line, and that these examples might be helpful for integrating the sokol headers or the sample code into your own project with the build system of your choice.
That is the practical value of the whole repository: not the samples, but the demonstration that a graphics application can be two source files and one compiler command.
Where sokol-samples is the wrong thing to build on
The first limitation is that these are samples, not a template. A sample exists to demonstrate one feature at its clearest, which means it deliberately skips the error handling, the configuration, the asset pipeline and the platform abstraction that a real application needs. Copying one as a starting point gets you the graphics working and the architecture wrong.
The second is the toolchain weight. The prerequisites are deno, cmake, a system C or C++ toolchain, and optionally ninja, plus on Linux the development packages for OpenGL, X11, ALSA and Vulkan, and on Windows the Vulkan SDK with a valid VULKAN_SDK environment variable. On Windows the README also requires you to build from a Visual Studio Command Prompt. That is a lot of setup for looking at a triangle.
The third is the manual build path, which is instructive but fragile. The three-directory side-by-side layout, the relative include paths, and the explicit framework lists are all things a real build system exists to remove. The README itself recommends copying the headers into your own source directory instead, which is an admission that this layout is a development convenience rather than a distribution model.
The fourth is that the sokol-app samples need the sokol-app harness, which lives in a different repository and is not in the samples repository. The libs directory provides some of the support code, but the harness is a separate dependency, so a sample is not self-contained.
The fifth is that the sokol-gfx validation layer and the assertion checks are development-time aids. The README notes that for Release builds you might want to add the compiler's optimisation flags and provide an NDEBUG define so that assert() checks and the sokol-gfx validation layer are removed, and it warns against doing that for Debug or Dev builds because the asserts and the validation layer give important feedback. A sample built for Release with those checks stripped is a sample you should not debug with.
How it compares to other C graphics samples
There are two other things you could do to evaluate a small C graphics stack.
The first is to read the library headers and its own documentation. That is faster for understanding the API surface and slower for understanding whether a backend actually works, because the samples are the only place where the same drawing code is exercised through D3D11, GLFW, HTML5, Metal and the sokol-app harness in one tree.
The second is to start from a larger framework with its own samples, where the samples are integrated into a build system and a broader project structure. That gives you a more realistic starting point but a much larger surface, and the samples are arranged to demonstrate the framework rather than to demonstrate the abstraction.
The specific trade here is the fibs meta build system. It is unusual for a sample repository to ship its own build orchestration, and it is unusual for that orchestration to cover native, WebAssembly, iOS and Android from one command set with named configurations. The cost is that you are now depending on fibs to understand the samples, and on deno as its runtime.
The manual build instructions are the counterweight to that. They show the same samples compiling with cc and cl directly, with no meta build system, in a few lines. So the repository supports two readings: use fibs if you want the whole matrix, or ignore fibs entirely if you only want to see what a sokol program looks like when compiled by hand.
That second reading is probably the one most people should take first, because the header count in sokol is large enough that understanding the shape of a program matters more than understanding the build.
Editorial conclusion
sokol-samples fits a developer evaluating the sokol library who wants to see a working example per backend before reading the headers, and it fits anyone assembling a small C graphics application who wants one build system across native, web, iOS and Android. It does not fit a project that already has its own build system and wants production tooling, since the samples are demonstrations and the manual build path is explicitly offered as guidance for integrating into your own project. Before adopting the samples as a reference, clone sokol and sokol-tools-bin beside sokol-samples as the directory layout requires, run ./fibs list configs to see the build configurations available for your platform, and keep the Debug and Dev configurations rather than Release so that the assertion checks and the sokol-gfx validation layer stay enabled while you work.
Frequently asked questions
How do I build and run a sokol sample?
Clone the repository, change into the directory and run ./fibs build, which builds the samples in the host platform's default release mode configuration. Then use ./fibs list targets --exe to see the executables and ./fibs run triangle-sapp-ui to run one.
What does fibs do in sokol-samples?
fibs is the meta build system the README points to, with documentation in the floooh/fibs repository. It provides the build, run, config, list, open and diag commands, and it owns toolchain installation for cross targets through commands such as ./fibs emsdk install and ./fibs android install.
How do I use a local sokol checkout with sokol-samples?
Clone sokol into a sister directory with git clone https://github.com/floooh/sokol ../sokol, then run ./fibs link sokol ../sokol and verify with ./fibs list imports. The samples will then use the linked repository instead of the imported version in the .fibs/imports subdirectory.
What are the prerequisites for building the sokol samples?
deno, cmake, your system's default C or C++ toolchain, and optionally ninja. On Linux you also need the development packages for OpenGL, X11, ALSA and Vulkan, and on Windows with Vulkan development you need the Vulkan SDK with a valid VULKAN_SDK environment variable and a Visual Studio Command Prompt.
Can I build a sokol sample without fibs?
Yes. The README shows manual command line builds, for example a Metal sample with cc on macOS, and a D3D11 sample with cl from a Visual Studio command prompt on Windows. It expects sokol-samples, sokol and sokol-tools-bin cloned side by side, and notes that you can copy the headers into your own source directory instead.
Official sources
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.
[](https://hysenlabs.com/projects/floooh-sokol-samples)Was this useful?