Open-source project
tgfrerer/island avatar
tgfrerer/island

Project Island: a Vulkan renderer built around hot reloading

๐ŸŒ‹๐ŸŽ Project Island is an experimental, hot-reloading Vulkan Renderer for Linux and Windows, written in C/C++.

1,295 stars49 forksC++MIT

At a glance

What is it?
Project Island is an experimental Vulkan renderer for Linux and Windows written in C and C++, whose whole purpose is to let you change C, C++, SLANG, GLSL, HLSL and image assets while the application keeps running. It gets there by splitting the engine into independently compilable modules and by organising rendering as a rendergraph that prunes passes with no effect.
Who is it for?
Adopt Project Island if you are prototyping a Vulkan renderer and you want to change shaders, code and assets without restarting, and you are prepared to work in an experimental codebase whose default branch is called wip. Do not adopt it as a production engine or as a foundation for a shipped game, because the project describes itself as experimental and a research-and-development effort.
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 1 day 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An experimental renderer whose purpose is the edit loop

Project Island is described as an experimental Vulkan Renderer for Linux and Windows, written in C/C++, and the first thing the README says about it is that Island is written for rapid prototyping and tweaking.

That sentence explains the rest of the design. Everything in the project exists to shorten the cycle between an idea and seeing it. The project supports Linux, on the desktop and on Raspberry Pi 5, and Windows, and the primary language is C++.

The stated performance target for the build is fast to compile. A full rebuild should take less than 5 seconds on a moderate multicore machine, and incremental builds often take less than 1 second. On Raspberry Pi 5, a typical project takes about 27 seconds of wall-clock time to compile from scratch. The 27 seconds is the honest number on a small ARM machine, and it is worth holding on to, because it is the difference between an edit-and-see loop and a reboot loop on a device with a small CPU.

The mechanism that gets there is modularity. Island is structured into strictly separated modules, which can be dropped in or out during Debug, while for Release you can build a single, statically linked and optimised binary. The two build modes are not two configurations of the same thing. Debug is a dynamic, reloadable assembly of modules; Release is a single binary.

The default branch of the repository is named wip, and the most recent release tag is v0.15.1-gpu_2d-rendergraph_visualizer from 2025-11-06, after v0.14.1-input-output from 2024-11-01 and v0.13.0-image-hot-reload from 2024-02-02. The tag names are the features, which tells you what the author was working on at each point. The last push was on 2026-10-13, and the repository is not archived, so the work is live.

The licence is MIT, and the topics list research-and-development and experimental alongside 3d-engine, engine, vulkan and vulkan-backend.

Hot reloading of code, shaders and images

The hot-reloading feature list is the core of the project, and it covers four different kinds of asset.

Code hot-reloading: an Island project is made from isolated C/C++ modules, each of which can be tweaked, recompiled at runtime, and automatically hot-reloaded. This is the part that no amount of shader hot reloading gives you, and it is the one that changes what you can learn about a renderer in an afternoon.

Shader hot-reloading covers SLANG, HLSL, GLSL, or SPIR-V shader source files. Shader files are automatically watched, and any change triggers a recompile, with Vulkan pipelines automatically rebuilt if needed. HLSL and GLSL shaders may use `#include` directives, and SLANG shaders can make full use of their `import` directives. Errors point at the shader file and line number and include a brief listing with the problematic lines highlighted in context, and dependencies are automatically watched for changes.

That last detail is the one that matters most in practice. A shader library that does not track its includes gives you a compile error in a file you did not touch, and the usual outcome is that you stop using includes. A tool that reports the error at the right file and line, with context, and that notices when a shared header changed, keeps the workflow intact.

Image hot-reloading works if you import images via `le_resource_manager`, which the README calls simple and recommended, and any image resource may automatically hot-reload when its source file changes.

And then there are code tweaks, which are a fourth category rather than a fifth. Near-instant in-code parameter tweaks for Debug builds, with no need to recompile, by using a special `LE_TWEAK()` macro. The distinction is worth making: hot reloading recompiles a module, a tweak changes a value in a running program. A tweak is the fastest possible iteration, and it is the one you use when you already know the code is right and you are trying values.

The repository structure supports this modularity directly. There is a modules/ directory, a 3rdparty/ directory for vendored dependencies, apps/ for the applications, resources/ for assets, scripts/, and a set of CMake files at the root: island_prolog.cmake, island_epilog.cmake, island_globals_utils.cmake, and a CMakeLists.txt.rename_artifact.in that shows the build is templated.

The rendergraph, and pruning the passes that do nothing

Rendering in Island is structured using passes, and the passes are executed on demand and synchronised automatically by evaluating a rendergraph. The automatic behaviour is the interesting part, and there are two parts to it.

The first is pruning. If a renderpass is detected to have no effect on the final image, it is automatically pruned. That sounds like an optimisation, and it is, but it is more than that: it means you can write a pass speculatively, leave it in the graph, and see whether it does anything. In a renderer written without a graph, a pass that writes nothing is invisible until you go looking for it.

The second is that the rendergraph can generate `.dot` files when requested, which can be drawn using graphviz. The visualisation is a debugging aid, and the README links a blog post with more about how Island builds its rendergraph.

The rendergraph visualizer, `le_rendergraph_visualizer`, is a separate tool that interactively visualises the current state of the renderer, displaying active and inactive renderpasses and their resource dependencies in real time. That is worth pausing on, because the combination of automatic pruning and a live view of what got pruned is a tight feedback loop: you add a pass, and you immediately see whether it is in the graph or was cut out of it.

The automatic GPU multiqueue behaviour follows the same logic. Renderpasses are automatically distributed onto any available render queues, and if resources need to be transferred between queue families, this happens automatically. A related README link covers how Island distributes workloads across renderqueues and synchronises them.

On top of that sits the Vulkan backend, and the README's claim about it is about what it removes rather than what it adds. The renderer takes care of most of the bureaucracy which comes with modern APIs: Vulkan resources are automatically synchronised and allocated when needed, most resource properties are inferred automatically based on the context of how the resource is being used, and pipelines are compiled and recompiled on demand. When compiled in Debug mode, Vulkan validation layers are loaded by default.

The reasoning behind the whole thing is stated plainly. The Vulkan backend allows access to new and experimental GPU features soon after they are released. A backend that infers resource properties from usage context and rebuilds pipelines on demand is a backend that does not have to be updated every time a driver exposes something new, which is the main practical reason experimental teams write their own renderer layer at all.

Debug affordances: the console, the visualizer and Tracy

The project has a set of tools that exist only for the developer, and they are the difference between a renderer you can experiment with and one you cannot.

The interactive console is the most unusual. If you add the `le_console` module to your app, it will listen on localhost port 3535, and if you connect to it via telnet or similar, it will provide an interactive console. You can use this to change settings on a running application, and to filter and monitor log messages. The README also notes that you can use reverse-ssh or similar to forward localhost::3535 and remotely connect to a running app from all over the world.

That last sentence deserves a second look, because it is a genuinely useful capability and also a genuine risk. A debug console on a port, reachable over reverse SSH, that can change settings on a running application, is an administrative interface with no authentication described in the visible documentation. The README describes it as a development tool and it is one, but the safety of shipping an application with that module enabled depends entirely on the network exposure, and the documentation does not say what happens with the module present in a Release build.

Tracy integration gives nano-second-resolution profiling via Tracy, and it is enabled by uncommenting a single line in the app CMakeLists file. The README notes that profiling works with both hot-reloading and optimised static builds, which is the useful part, because a profiler that only works in your debug build is a profiler that tells you about a build you do not ship.

The rendergraph visualizer, described above, is the third. Between the console, the visualizer and Tracy, the debugging surface is considerably wider than most experimental renderers offer.

The repository also carries several platform and topic-specific documents that indicate the scope of the supported configurations: README_RPI5.md for the Raspberry Pi 5, README_WINDOWS.md for Windows, README_hotreload_debugging.md for the hot reload workflow, README_HINTS.md, and legacy_sdk_installation_instructions.md for the older SDK layout. There is a .appveyor.yml and a .travis.yml alongside the GitHub Actions workflow for the C and C++ build, an island.code-workspace for VS Code, and a .personaltypes.py, which is an unusual file to see and suggests some per-developer configuration lives in the repository.

The Vulkan feature set Island reaches for

Beyond the rendergraph, the README lists the specific GPU capabilities the renderer is built around, and the list is more informative than a generic feature list would be.

Multiview rendering using `GL_EXT_multiview`, where renderpass image attachments can be layered images and may declare a viewMask bitfield, and if such a bitfield is detected, rendering is automatically broadcast to the layers covered by it. The README's example is that a single renderpass is enough to render into 6 faces of a cubemap. That is a real saving in a renderer, because the alternative is six passes and six render targets, and the automatic broadcast means the author of the pass does not have to think about it.

Vulkan Video Decode gives hardware accelerated video decode using just the new Vulkan Video API, and no external decoding dependencies, synchronising video images implicitly and simply. No external decoder is a meaningful constraint, since the usual approach is to decode to CPU memory and upload, and this keeps the frames on the GPU.

Straight to video is a set of swapchain options. Island can render straight to screen using the direct rendering swapchain, or use any number of available options for a window-based Vulkan swapchain, and it is easy to render straight to an mp4 file via ffmpeg, or to an image sequence without showing a window, by selecting the appropriate `le_swapchain` specialisation. Rendering a frame sequence with no window at all is a capability that turns the renderer into an offline tool, which is how you benchmark or batch-render.

Multi-window support lets you hook up multiple swapchains to a single application, and you can dynamically add and remove swapchains while the application is running, which the README calls out as particularly useful for multi-window scenarios.

Then the helper modules. There are minimal effort helpers to enable multisampling, import images, and import, display and use fonts. The core `le_exr` module loads and saves OpenEXR images in 16-bit float and 32-bit float variants. And `le_path` gives 2D paths with curves using a useful subset of the SVG command palette.

The gamepad support is a smaller feature with a specific design: the default camera can be steered with a gamepad, just connect your gamepad and you are set, and application windows can decide whether they want to subscribe to gamepad events, and to which gamepads to subscribe to. That per-window opt-in is the detail that makes it usable in a multi-window application.

Where Project Island is the wrong tool

There are three limits, and the first one is stated in the repository itself.

The first is the experimental label, and everything else follows from it. The default branch is named wip. The topics include experimental and research-and-development. The README describes the project as experimental. The last tagged release is v0.15.1 from 2025-11-06, while the working tree is on the wip branch, and the release history has gaps, with 2024-02-02, 2024-11-01 and 2025-11-06 the only visible dates. A renderer on a wip branch is a renderer whose API you should expect to change under you, and that is fine for a research prototype and wrong for a product.

The second is the platform and driver surface. The README commits to giving access to new and experimental GPU features soon after they are released, and that is the point of writing your own Vulkan backend, but it also means the renderer is exposed to whatever the driver exposes, including its bugs. The multiview extension, the Vulkan Video API, and the general expectation of bleeding-edge features all mean that a machine with a current but imperfect driver is a supported and unpredictable environment. The automatic inference of resource properties and the automatic pipeline rebuilds remove a lot of Vulkan boilerplate, and they also remove the explicit steps where a mistake would otherwise surface as a validation error.

The third is the debug console, which I mentioned above and which deserves repeating in the limitations list. A module that listens on port 3535, accepts telnet, can change settings on a running application and can be forwarded over reverse SSH is an administrative channel. It is described as a development tool, but nothing in the visible documentation describes authentication, TLS, or what happens in a Release build with the module present. A team shipping anything with that module enabled needs to answer those questions before the application reaches a user.

The comparison to make is with a production engine, and it is not close. If the goal is a shipped game or a product with a support commitment, the established engines give you a validated driver layer, a documented toolchain and a maintenance team, and Island gives you an edit loop you cannot get elsewhere. The Raspberry Pi target is the case where the trade is most favourable, since a 27 second rebuild on a Pi 5 is a real constraint that a desktop engine does not have to face.

Editorial conclusion

Adopt Project Island if you are prototyping a Vulkan renderer and you want to change shaders, code and assets without restarting, and you are prepared to work in an experimental codebase whose default branch is called wip. Do not adopt it as a production engine or as a foundation for a shipped game, because the project describes itself as experimental and a research-and-development effort. Verify first that your Vulkan driver and the shader languages you intend to use are supported, that the module you want to hot reload is one of the isolated ones, and that the build tooling on your platform matches the per-platform instructions in the repository.

Frequently asked questions

What is Project Island and what does it do?

It is an experimental Vulkan renderer for Linux and Windows written in C and C++, built for rapid prototyping. It hot-reloads application code, SLANG, HLSL, GLSL and SPIR-V shaders, and image assets while the application keeps running, and it organises rendering as a rendergraph that prunes passes with no effect on the final image.

How does the Island hot reloading work?

An Island project is made from isolated C/C++ modules that can be recompiled at runtime and reloaded automatically, shader files are watched and recompiled with pipelines rebuilt when needed, and image resources imported through le_resource_manager reload when their source changes. Debug builds also support near-instant parameter changes through the LE_TWEAK() macro with no recompile.

What is the Island rendergraph visualizer?

le_rendergraph_visualizer interactively visualises the current state of the renderer, showing active and inactive renderpasses and their resource dependencies in real time. The rendergraph can also generate .dot files for graphviz when requested.

Is Project Island suitable for production use?

The README describes it as experimental and the repository's default branch is named wip, with the most recent release tag v0.15.1 dated 2025-11-06. The README also documents a debug console module that listens on localhost port 3535 and can change settings on a running application, with no authentication described.

Official sources

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

Was this useful?