Desktop apps in PHP, compiled to native code and drawn on the GPU — no browser engine.
You write screens as PHP classes and their layout as small .rk templates. RageKit compiles the
PHP to machine code with TypePHP, turns the templates into a
Slint UI, and produces an ordinary executable.
composer create-project ragekit/starter myapp # a new app, ready to build (see Get started)Status: experimental (0.x). Linux is where it's built and tested. Windows works but is tested less. macOS isn't supported yet: it hasn't been built or tested there. APIs will change.
For open-source apps only. Apps built with RageKit are GPLv3 (see License).
This project is vibe-coded. It was designed by its author and written largely with an AI coding assistant (Claude). Every feature has automated tests (unit tests plus end-to-end runs of the demo apps), but it is young and not battle-tested. Read the code before you trust it with anything important.
// src/CounterScreen.php — state is public properties, handlers are methods
final class CounterScreen extends \RageKit\Screen
{
public int $count = 0;
public string $name = '';
/** @var list<string> */
public array $history = [];
// React Native-style styles: named style objects, used by name in the template
public const STYLES = [
'card' => ['backgroundColor' => '#18181b', 'borderRadius' => 12, 'padding' => 16, 'gap' => 8],
'tags' => ['flexDirection' => 'row', 'flexWrap' => 'wrap', 'gap' => 6],
];
public static function template(): string
{
return 'templates/CounterScreen.rk';
}
public function greeting(): string
{
return $this->name === '' ? 'Type your name above' : "Hello, " . $this->name . '!';
}
public function increment(): void
{
$this->count++;
$this->history[] = "+1 → {$this->count}";
}
}<!-- templates/CounterScreen.rk: Rageblade, compiled ahead of time -->
<View style="card">
<Label text="Count: {{ $count }}" size="title" />
<Button text="+" onClick="increment" />
<Entry value="{{ $name }}" />
<Label text="{{ greeting() }}" />
@if (count($history) > 0)
<View style="tags">
@foreach ($history as $entry)
<Badge text="{{ $entry }}" variant="secondary" />
@endforeach
</View>
@endif
</View>// src/CounterApp.php — the app: its first screen (and its state, title, size…)
final class CounterApp extends \RageKit\App
{
protected function firstScreen(): \RageKit\Screen
{
return new CounterScreen();
}
}
// main.php
function main(): void
{
(new CounterApp())->run();
}After every event the window shows the screen's new state; there is no manual re-rendering.
More from demo/kitchen-sink:
| Desktop features | Feedback elements |
|---|---|
![]() |
![]() |
| A dialog | The Material kit |
![]() |
![]() |
- Compiled PHP. TypePHP compiles your PHP (a large subset of the language) to C++ and then to machine code.
- A drawn UI. Slint renders the widgets itself, so you get custom looks (rounded cards, shadows, themes) on every platform. They are not the OS's own widgets.
- Rageblade templates and React Native styles. Blade-style
{{ }},@foreach,@ifand@style, typed and compiled ahead of time; style objects with React Native's property names;<View>with flexbox (including wrapping) and absolute positioning. - Kits. The same template builds with
shadcn(dark, minimal) ormaterial(Material 3), or with a kit you write.ragekit eject shadcncopies a kit into your app to restyle it freely. - Hot reload.
ragekit devreloads templates in place and restarts only your PHP when it changes, keeping the screen's state (Linux and Windows). - Native modules. Device and OS features as runtime-loaded libraries with a PHP API, starting with audio, HTTP, crypto (Ed25519, SSH signatures), the OS keyring, desktop notifications and a tray icon. An app still runs when a module's library is missing.
- Your own title bar. A layout frames screens in a frameless window with an app-drawn bar that moves, resizes, maximises and closes the window (Windows and Linux).
- Nano builds. One small executable with a stripped-down PHP runtime compiled in.
RageKit's claim is "compiled, GPU-rendered, no Chromium" — and it tries not to claim more:
- A normal build contains your compiled code plus PHP's runtime (linked statically on Linux, shipped as DLLs on Windows).
- A Nano build (
ragekit: { nano: true }) compiles a stripped-down PHP runtime (php-nano) into the executable: no PHP libraries next to it, no bytecode interpreter, noeval/include, no PHP networking (use thehttpmodule instead). It is still PHP's engine, just smaller. - Slint's library (
libslint_cpp, about 40 MB on Linux, 27 MB on Windows) and RageKit's small bridge library ship next to the executable.
Measured on the demo apps with Slint's software renderer: about 27 MB of private memory on Linux for a normal build and 20 MB for Nano. A Nano executable is about 3 MB; a normal one is 51 MB with the private PHP linked in, or 0.3 MB plus PHP's library (6 MB) when it links your system's PHP. A calculator app on Windows used 13 MB normal and 8 MB Nano. GPU renderers draw shadows but use far more memory, mostly driver overhead.
- TypePHP compiles a subset of PHP: frameworks like Laravel won't compile. See TypePHP's documentation for what's unsupported.
- Your PHP runs on the UI thread: long work freezes the window. Only native modules can do work on other threads so far.
- No PHP networking functions in Nano builds; the
httpmodule works there. - Accessibility and input methods depend on Slint, not the OS's widgets.
Start a new app from the starter project:
composer create-project ragekit/starter myapp
cd myapp
composer start # build, then run the appcreate-project also runs ragekit setup, which installs TypePHP and Slint (shared per user, so
only the first app downloads them) and checks your system. You need PHP 8.4+, Composer, git and a
C++ compiler. On Windows that's Visual Studio 2022 Build Tools; when they're missing,
create-project offers to install them. You also need 7-Zip. The full list and a tour of the app
are in Getting started.
To run the demo apps instead, clone this repository:
git clone https://github.com/ragekit-php/ragekit.git && cd ragekit
./setup.sh # Composer, then TypePHP + Slint (shared per user), then a check
cd demo/kitchen-sink && ../../bin/ragekit runOn Windows, run setup.ps1 instead of setup.sh.
- Getting started — requirements, a first app, building and running
- The toolchain — TypePHP, Slint,
ragekit setup/doctor, normal vs Nano - Templates —
.rksyntax, elements, components - Moving between screens — the navigator: push, back, a window's stack of screens
- App-wide state — stores: the signed-in user, settings;
$storein templates - App links —
myapp://…links, one running instance, registering the scheme - Generators —
ragekit make:screenand friends, where things go,stub:publish - Kits — choosing and writing UI kits
- Native modules — using and writing modules (audio, http, crypto, keyring, notifications, tray)
- Dev mode —
ragekit devand hot reload - Architecture — how the repository is laid out
- Changelog — what changed in each version, and what counts as breaking
| Demo | Shows |
|---|---|
demo/calculator |
logic in plain PHP, a keypad from a constant with each |
demo/counter-slint |
state, two-way input, a child component, a second window |
demo/kitchen-sink |
every core element and the desktop features (a chat, timers, notifications, tray, keys, recording), as sections in a sidebar, with its own title bar (--kit=material to compare kits) |
demo/kit-demo |
an app's own kit (kits/icons) with SVG icons embedded at build time |
demo/player |
the audio module: play, pause, progress, volume |
demo/titlebar |
a Window subclass: frameless window, own title bar with a search box and window buttons |
demo/navigator |
app state and moving between screens in one window: sign in and out through a store, push, back (← and Alt+Left), state kept, a dialog and a toast |
demo/fetch |
the http module: a GitHub API lookup and a download with progress (needs the internet) |
Run one with ../../bin/ragekit run from its folder, or ../../bin/ragekit dev for hot reload.
RageKit is licensed under the GNU General Public License v3. Its runtime is compiled into every app it builds, so apps you distribute are GPLv3 too. It builds on TypePHP, Slint, PHP and others; see third-party notices for their licenses and what they mean for your app.
Closed-source apps aren't possible today. Two things stand in the way:
- RageKit's own runtime is GPLv3. This may change later (for example with an exception for the runtime); it isn't decided.
- Slint, which draws the UI, is GPLv3 for RageKit. Slint also offers a royalty-free license that allows closed-source desktop apps, but that license doesn't allow distributing a framework that exposes Slint's API, which is what RageKit does. Whether an app built with RageKit could still use Slint's royalty-free license for itself is an open question we haven't asked Slint yet.
RageKit is an independent project, not affiliated with the TypePHP or Slint projects.




