An immediate mode UI rendering engine built with C++ WebAssembly and Raylib. Ramla Engine provides an alternative to DOM-based rendering by mapping a custom DSL (Domain Specific Language) directly to immediate mode draw calls, delivering high-performance graphics in web browsers.
Traditional web UIs rely on the DOM (Document Object Model) for rendering, which can become a performance bottleneck for complex interfaces or real-time graphics. Ramla Engine takes a different approach:
- Immediate Mode Rendering: Direct draw calls without intermediate DOM manipulation
- Custom DSL: High-level UI description language that compiles to optimized graphics commands
- WebAssembly Performance: Near-native performance in web browsers
- Raylib Backend: Proven graphics library with cross-platform support
This architecture enables fluid 60+ FPS interfaces, real-time data visualizations, games, and other graphics-intensive web applications that would struggle with traditional DOM rendering.
- Immediate Mode UI: Direct pixel manipulation without DOM overhead
- WebAssembly Performance: High-performance C++ code running in browsers
- Embedded Lua Scripting: High-level UI logic with Lua integration (compiled as C++ for simplicity)
- Custom DSL Mapping: Declarative UI syntax compiled to draw calls
- Cross-Platform: Runs on any modern browser supporting WebAssembly
- Modern Tooling: Full IDE support with clangd configuration
- Responsive: Hardware-accelerated rendering on desktop and mobile
- Simplified Build: Single C++ compiler for all components
git clone <your-repo-url>
cd ramla-engine
chmod +x setup.sh
./setup.sh
make serve
Then open http://localhost:9999 in your browser to see the immediate mode rendering demo.
If you prefer to set up dependencies manually:
- Git - For cloning repositories
- Python 3 - For running the local server
- Make - For building the project
# Clone Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# Install and activate latest version
./emsdk install latest
./emsdk activate latest
# Set up environment (run this in each terminal session)
source ./emsdk_env.sh
cd ..
# Clone Raylib
git clone https://github.com/raysan5/raylib.git
# Build Raylib for WebAssembly
cd raylib/src
source ../../emsdk/emsdk_env.sh
make PLATFORM=PLATFORM_WEB
cd ../..
# Set up Emscripten environment
source emsdk/emsdk_env.sh
# Build the WebAssembly module
make
# Or build and serve in one command
make serve
ramla-engine/
├── src/
│ └── main.cpp # Core immediate mode rendering logic
├── public/
│ └── index.html # WebGL canvas container
├── lua/ # Lua scripting engine (submodule)
├── emsdk/ # Emscripten SDK (auto-installed)
├── raylib/ # Raylib graphics library (auto-installed)
├── .clangd # IDE configuration for syntax highlighting
├── compile_commands.json # Build database for IDEs
├── Makefile # Build configuration
├── CMakeLists.txt # CMake build configuration
├── setup.sh # Automated setup script
└── README.md # This file
Command | Description |
---|---|
make |
Build the WebAssembly module |
make clean |
Remove build artifacts |
make serve |
Build and serve locally (Python) |
make serve-node |
Build and serve locally (Node.js) |
make watch |
🚀 Development mode - Build, serve, and auto-rebuild on file changes with animated feedback |
make help |
Show all available commands |
- Lua Scripting: High-level UI logic and component definitions
- DSL Input: High-level UI description (planned)
- Compilation: DSL transforms to optimized draw commands
- WebAssembly Execution: C++ rendering logic runs in browser
- Raylib Backend: Hardware-accelerated graphics calls
- Canvas Output: Direct pixel manipulation via WebGL
The current implementation demonstrates the foundation:
- WebAssembly module initialization
- Immediate mode rectangle rendering
- Text rendering with custom positioning
- 60 FPS rendering loop
- Lua-based UI scripting and component system
- Custom DSL parser and compiler
- Layout management system
- Event handling for interactive UIs
- Component abstraction layer
- Performance profiling tools
make watch
The project includes configuration for modern IDEs:
- VS Code/Cursor - Full IntelliSense with C++, Raylib, and Emscripten
- CLion - CMake support with proper include paths
- Any Editor - Uses clangd language server
-
Add Drawing Functions:
void DrawCustomWidget(int x, int y, int width, int height) { DrawRectangle(x, y, width, height, BLUE); DrawText("Custom Widget", x + 10, y + 10, 20, WHITE); }
-
Update Main Loop:
void UpdateDrawFrame() { BeginDrawing(); ClearBackground(DARKGRAY); DrawCustomWidget(100, 100, 200, 50); EndDrawing(); }
Development Build (faster compilation):
make CXXFLAGS="-std=c++17 -O0 -g"
Production Build (optimized):
make CXXFLAGS="-std=c++17 -O3 -DNDEBUG"
Traditional DOM Rendering:
- Layout recalculation overhead
- Style computation and cascade
- Reflow and repaint cycles
- JavaScript bridge overhead
Ramla Engine Immediate Mode:
- Direct pixel manipulation
- Predictable rendering costs
- No layout thrashing
- Minimal JavaScript overhead
The immediate mode approach excels in scenarios with:
- High-frequency updates (real-time data)
- Complex animations
- Custom graphics requirements
- Performance-critical applications
# Build the project
make
# Copy public folder to docs/ or gh-pages branch
cp -r public/* docs/
Simply point your deployment to the public/
folder after building.
# Production build
make clean && make
# Serve with any web server
cd public
python3 -m http.server 8080
"Module is not defined"
- Make sure you're serving through a web server, not opening HTML directly
- Check browser console for specific errors
"emcc: command not found"
source emsdk/emsdk_env.sh
"raylib.h not found"
cd raylib/src && make PLATFORM=PLATFORM_WEB
Build errors
make clean && make
VS Code/Cursor IntelliSense not working:
- Install the clangd extension
- Disable C/C++ extension (conflicts with clangd)
- Restart the editor
Missing autocomplete:
- The
.clangd
andcompile_commands.json
files provide full IDE support - Make sure your editor supports the Language Server Protocol
This project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/immediate-mode-feature
) - Commit your changes (
git commit -m 'Add immediate mode feature'
) - Push to the branch (
git push origin feature/immediate-mode-feature
) - Open a Pull Request
Ramla Engine - Bringing immediate mode UI rendering to the web through WebAssembly and Raylib.