DEV Community

Cover image for ✨ Want to make your first PR?
Artem Romanov
Artem Romanov

Posted on

✨ Want to make your first PR?

🧱 AutoCAD is now in the browser.
🖼️ Photoshop is now in the browser.
🫵 Maybe it’s time you learn something about WebAssembly.

🧠 What are you talking about?

I wrote a simple procedural noise visualizer in C++ using Raylib, Raygui, and compiled it to WASM to run directly in the browser.
👉🏻 Demo
👉🏻 Source Code

🚀 Why should you care?

This project is contributor-friendly by design. If you want to add your own noise generator, the process is simple:

  • Clone the repo from GitHub
  • Create a new .cpp file in src/generators/
  • Include the required headers
  • Inherit from the INoiseGenerator interface
  • Implement your generator logic
  • Define the arguments your generator uses
  • Register your generator That’s it. All parameters are automatically connected to the GUI via raygui — no need to write any UI code. You can focus purely on the noise logic — the rest (rendering, UI, interaction) is already taken care of. Any help from more experienced developers is also very welcome. Full contributor guide here.

🕸️ What is WASM?

WebAssembly is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

Basically it means that we can compile most of the popular now programming languages into WASM and run your program into the browser.
Write a desktop app -> compile with Emscripten -> open it in the browser.

💡 What's the idea?

My idea was to create a minimalistic WebAssembly demo that visualizes procedural noise.
I wanted something simple:

  • A single .cpp file as the core.
  • Clean GUI with raygui for changing various arguments of noise generator in realtime.
  • Easy to contribute architecture.
  • Full CI/CD, Docker and other DevOps things.

🛠️ So, how do we do that?

Let’s start small. First, install Emscripten — the toolchain that lets you compile C/C++ code into WebAssembly. You can get it here.
Once installed, you can compile and run a simple C++ program like this:

#include <stdio.h>

int main() {
    printf("Hello World\n");
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Compile it with emcc hello.c -o hello.html command and run hello.html in your browser.

You’ll see the output in the browser’s developer console:

Hello World in a browser console

That’s a good start. But plain text isn't very exciting — what if we want graphics, maybe even interactive ones?

🎮 Raylib

To render graphics and build interactive apps, we need a graphics library. For that we need to use a popular and in my opinion, really great graphics library Raylib.
Raylib is:

  • Simple to learn and use
  • Cross-platform (Linux, Windows, macOS — and now the browser via WASM)
  • Actively developed and well-documented
  • Works great with Emscripten With Raylib, we can create a graphical window (even in the browser), draw shapes, render textures, and handle input — all with clean, low-boilerplate code.

For UI controls like sliders, checkboxes, and buttons, I use raygui. It’s just a single header file, which makes it perfect for small, self-contained projects like this one.

🔧 Next step: compiling Raylib to WebAssembly

To run everything in the browser, we need to compile Raylib and our code using Emscripten. Raygui doesn’t require separate compilation — it's just a header.

A good starting point is this guide on StackOverflow:
Guide

In short:

  • Build Raylib as a static library using emcmake and emmake
  • Link your C++ code with the library using emcc
  • Serve the generated .html/.js/.wasm files in a browser
  • In my case, the whole project builds using a simple CMakeLists.txt, so once Emscripten is set up, compiling it is straightforward.

🪟 What do we have now?

This example of basic window with code snippet ideally represents our current state.

📈 3D Visualization

Using functions from the Raylib cheatsheet, we can take it further:

  • Create a basic GUI with instructions and sliders
  • Enable 3D camera mode
  • Draw a grid of cubes where height = noise value
  • Add FPS counter and interaction Result — a dynamic 3D visualization of procedural noise: Basic Implementation

🧩 Making project extendable

From the beginning, I wanted this to be easy to extend — especially for people who want to add custom noise generators.

The classic approach would be something like:

if (name == "Perlin") return new PerlinNoise();
else if (name == "Simplex") return new SimplexNoise();

Enter fullscreen mode Exit fullscreen mode

But that doesn’t scale. Every time someone adds or renames a generator, they’d have to modify central logic — not great for contributions.

After a bit of research I found about C++ Static Registration Pattern. This pattern creates plugin like architecture, often used in game engines.

This pattern works like this:

  • A static registry holds all available noise generators.
  • Each generator registers itself at static initialization time using a macro.
  • The main app doesn't need to know or care about what generators exist — it just asks the registry to create one by name.

This lets contributors drop in a new file, inherit from INoiseGenerator, and register their class like so:
REGISTER_GENERATOR(MyCoolNoise, MyCoolNoise::create);
Then, the factory can create it with:
INoiseGenerator* gen = GeneratorRegistry::create("MyCoolNoise");

No if blocks, no central changes. You can treat generators like plugins.

⚙️ Other things

  • Graph color customization — Color of the 3D graph is configurable, making it easier to visually distinguish different generators or modes.
  • CI/CD — GitHub Actions pipeline builds the project and ensures that any new commit compiles correctly. Planned: automatic deploy to GitHub Pages.
  • Docker — Development container with Emscripten, Raylib, and build tools preinstalled. No need to set up anything manually — just clone and run.
  • Code style — The repository includes .clang-format for consistent C++ style across all contributors.
  • CMake-based build system — Cross-platform and ready for WebAssembly builds via emcmake.

✅ Final words

Thanks to everyone who made it to the end of this post — I appreciate your time.

If you're interested in procedural generation, C++ in the browser, or just want to play with Raylib + WebAssembly — feel free to check out the project, give it a ⭐ on GitHub, or open a PR.

I didn’t cover everything (debugging Emscripten, weird linker issues, toolchain problems, ...) — otherwise, this post would be twice as long.
But I’ve described all the key steps to get it working and extend it.

Help wanted:

  • Writing better documentation
  • Adding .clang-tidy and other static analysis tools
  • Expanding test coverage and build checks
  • New generators, render modes, UX improvements — anything welcome

This is a small project, but it's a real, working example of modern C++ apps running in the browser — something that seemed impossible not so long ago.

Thanks again — and feel free to fork, break things, or build something cool on top of it. <3

Top comments (0)