1 · What Is SDL3?

Simple DirectMedia Layer 3 (SDL3) is the 2025 evolution of the venerable cross‑platform multimedia library. Version 3.2.0, the first stable release, arrived in January 2025 and the API has since moved to the 3.2.x maintenance branch.

SDL3 keeps the “batteries‑included” ethos of SDL2 while refactoring the API for consistency, adding a GPU API, async file‑I/O, improved audio streams, modern input‑device handling and much richer platform abstractions.

Note: Existing SDL2 projects can still compile unchanged by dropping in the sdl2‑compat shim, then migrating incrementally.

2 · Installation Options

2.1 macOS (Apple Silicon & Intel)

Homebrew provides ready‑made bottles:

brew install sdl3
brew install sdl3_image sdl3_mixer sdl3_ttf
Bottles are universal for arm64 and x86_64.

2.2 Linux

Until distro packages catch up, build from source:

# Build & install SDL3
tar -xf SDL3-3.2.4.tar.gz
cd SDL3-3.2.4
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install

Note: Pass -DSDL_STATIC=ON if you want a static archive.

2.3 Windows (MSVC / MinGW‑w64)

3 · Your First SDL3 Program

// hello_sdl3.c
#include <SDL3/SDL.h>

int main(int argc, char **argv)
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;

    SDL_Window   *win  = SDL_CreateWindow("SDL3 ❤", 800, 600, 0);
    SDL_Renderer *rend = SDL_CreateRenderer(win, NULL, 0);

    bool running = true;
    while (running) {
        SDL_Event e;
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_EVENT_QUIT) running = false;
        }
        SDL_SetRenderDrawColor(rend, 30, 30, 40, 255);
        SDL_RenderClear(rend);
        SDL_RenderPresent(rend);
    }

    SDL_DestroyRenderer(rend);
    SDL_DestroyWindow(win);
    SDL_Quit();
    return 0;
}

This example opens a window, processes events, clears the screen and flips the back‑buffer every frame. It demonstrates the SDL_Init, SDL_CreateWindow and SDL_CreateRenderer workflow.

4 · Core Concepts & Subsystems

4.1 Initialization Flags

Call SDL_InitSubSystem for laser‑focused start‑ups, or SDL_Init(SDL_INIT_EVERYTHING); for one‑shot.

4.2 Window & Renderer Separation

Unlike SDL2, the new GPU API lets you bypass the legacy 2‑D renderer and talk to modern back‑ends (Metal, Vulkan, D3D12, Gnm) through SDL_CreateGPURenderDevice and friends.

4.3 Events & Input

The event queue remains SDL_PollEvent()‑centric but now includes high‑fidelity tablet Pen Events, separate logical keyboards, and multiple mice tracking.

4.4 Audio Streams

The audio layer moved from callback‑pushed buffers to SDL_AudioStream, letting you write, mix and resample on demand. Devices can be swapped live (USB headset unplug, Bluetooth speaker, …).

5 · Images, Fonts & Audio Codecs

Note: All satellite libs now share the same major number (3) and a consistent CMake package name: find_package(SDL3_image).

6 · What’s New Since SDL2?

For a living list, see the SDL Wiki “New Features” page.

7 · Migrating from SDL2 → SDL3

  1. Add sdl2-compat alongside SDL3 to compile unmodified source.
  2. Replace #include <SDL.h> with #include <SDL3/SDL.h>.
  3. Rename opaque structs: SDL_Window* → SDL_WindowID, SDL_Texture* → SDL_GPUTex*, etc.
  4. Swap deprecated SDL_Render* calls for GPU API equivalents where performance matters.
  5. Remove manual audio callbacks in favour of SDL_AudioStream.

Note: The official README‑migration.md in the SDL repo tracks every symbol change.

8 · CMake / Meson Integration

8.1 CMake (Recommended)

cmake_minimum_required(VERSION 3.25)
project(MyGame LANGUAGES C)

find_package(SDL3 CONFIG REQUIRED)

add_executable(MyGame src/main.c)
target_link_libraries(MyGame SDL3::SDL3)

8.2 Meson

sdl3_dep = dependency('sdl3', required : true)
executable('my_game', ['main.c'], dependencies : sdl3_dep)

9 · Advanced Topics

10 · Further Reading & Community