@gtkx/gl 0.21.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,118 +1,173 @@
1
1
  <p align="center">
2
- <img src="logo.svg" alt="gtkx" width="180" />
2
+ <img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/logo.svg" alt="GTKX" width="100" />
3
3
  </p>
4
4
 
5
- # gtkx
5
+ <h1 align="center">GTKX</h1>
6
6
 
7
- gtkx is a framework for building native GTK4/libadwaita desktop applications with React, TypeScript, and JSX. You write declarative JSX whose element types are GTK widget names; a custom react-reconciler maps that tree to live GObject instances, while a Rust napi addon owns the single GLib main-loop thread and performs every call into GTK. A build-time generator turns GObject-Introspection (GIR) XML into typed bindings, JSX element types, and reconciler metadata, and a Vite-based CLI provides scaffolding, a hot-reloading dev server, single-file production bundling, and GTK-asset integration.
8
-
9
- Homepage: [gtkx.dev](https://gtkx.dev)
7
+ <p align="center">
8
+ The React framework for Linux.<br />
9
+ Build GTK4 and Adwaita apps in TypeScript, with React components and hooks driving GNOME's own widgets. What you ship is a GNOME app.
10
+ </p>
10
11
 
11
- ![gtkx demo](demo.gif)
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/v/create-gtkx?color=cb3837&logo=npm&label=create-gtkx" alt="npm version" /></a>
14
+ <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/dm/create-gtkx?color=cb3837&logo=npm&label=downloads" alt="npm downloads" /></a>
15
+ <img src="https://img.shields.io/badge/node-%E2%89%A524-339933?logo=node.js&logoColor=white" alt="Node >= 24" />
16
+ <a href="https://github.com/gtkx-org/gtkx/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue.svg" alt="License: MPL-2.0" /></a>
17
+ <a href="https://github.com/gtkx-org/gtkx/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/gtkx-org/gtkx/ci.yml?branch=main&logo=github&label=CI" alt="CI status" /></a>
18
+ <img src="https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white" alt="TypeScript" />
19
+ </p>
12
20
 
13
- ## Prerequisites
21
+ <p align="center">
22
+ <a href="https://gtkx.dev">Homepage</a> &middot;
23
+ <a href="https://gtkx.dev/guide/why-gtkx">Documentation</a> &middot;
24
+ <a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> &middot;
25
+ <a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
26
+ </p>
14
27
 
15
- This is a Linux desktop framework, not a browser/DOM renderer. You need:
28
+ ---
16
29
 
17
- - **Node.js** the engines floor is Node `>=24`.
18
- - **pnpm** — the workspace package manager, provisioned via Corepack from the `packageManager` field.
19
- - **Rust toolchain** — 2024 edition with a C linker, plus the napi-rs CLI and Node N-API headers, to compile the native addon. A nightly toolchain is additionally required for the coverage, asan, and miri paths.
20
- - **libffi** — for dynamic CIF construction and closures in the native addon.
21
- - **GTK4 and libadwaita** development libraries, plus the broader GNOME library set the examples use (GtkSourceView, WebKitGTK, VTE, GStreamer, etc.), with `pkg-config`.
22
- - **GLib/GObject** shared libraries present at build and run time; gtkx resolves GTK symbols dynamically by name.
23
- - **GObject-Introspection** development data and system GIR files (read by codegen), plus `glib-compile-resources` and `glib-compile-schemas` for asset compilation.
24
- - **A headless Wayland compositor** (Weston, or Sway when `GTKX_COMPOSITOR=sway`) and software GL/Vulkan rasterization to run GTK tests and benches without a GPU.
25
- - **git**, for repository initialization during scaffolding.
30
+ GTKX generates fully typed bindings for the entire GTK4 and Adwaita surface directly from GObject-Introspection. On top of those bindings you get the React programming model: components and hooks driving GObject instances, with Fast Refresh while you develop.
26
31
 
27
- For the containerized CI path you additionally need Docker; the CI image pins the full GTK/Rust/Node toolchain.
32
+ <p align="center">
33
+ <img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/examples/tutorial/assets/screenshot.png" alt="The Tasks app: an Adwaita window with a sidebar of smart views and colored lists on the left, and a boxed task list on the right." />
34
+ </p>
28
35
 
29
- ## Getting started
36
+ <p align="center">
37
+ <em>The Tasks app you build in the <a href="https://gtkx.dev/tutorial/">tutorial</a>.</em>
38
+ </p>
30
39
 
31
- ```sh
32
- git clone https://github.com/gtkx-org/gtkx.git
33
- cd gtkx
34
- corepack enable
35
- pnpm install
36
- pnpm build
40
+ ## Demo
41
+
42
+ The intrinsic elements in this snippet render GTK4 widgets, and ordinary React hooks and events drive them:
43
+
44
+ ```tsx
45
+ import * as Gtk from "@gtkx/gi/gtk";
46
+ import { GtkApplication, GtkApplicationWindow, GtkBox, GtkButton, GtkLabel } from "@gtkx/jsx/gtk";
47
+ import { createRoot, quit } from "@gtkx/react";
48
+ import { useState } from "react";
49
+
50
+ const Counter = () => {
51
+ const [count, setCount] = useState(0);
52
+
53
+ return (
54
+ <GtkApplicationWindow
55
+ title="Hello GTKX"
56
+ defaultWidth={400}
57
+ defaultHeight={300}
58
+ onCloseRequest={quit}
59
+ >
60
+ <GtkBox
61
+ orientation={Gtk.Orientation.VERTICAL}
62
+ spacing={20}
63
+ marginTop={40}
64
+ marginBottom={40}
65
+ marginStart={40}
66
+ marginEnd={40}
67
+ valign={Gtk.Align.CENTER}
68
+ halign={Gtk.Align.CENTER}
69
+ >
70
+ <GtkLabel cssClasses={["title-1"]}>Welcome to GTKX!</GtkLabel>
71
+ <GtkLabel cssClasses={["title-2"]}>{`Count: ${count}`}</GtkLabel>
72
+ <GtkButton
73
+ label="Increment"
74
+ onClicked={() => setCount((c) => c + 1)}
75
+ cssClasses={["suggested-action", "pill"]}
76
+ />
77
+ </GtkBox>
78
+ </GtkApplicationWindow>
79
+ );
80
+ };
81
+
82
+ const App = () => (
83
+ <GtkApplication>
84
+ <Counter />
85
+ </GtkApplication>
86
+ );
87
+
88
+ createRoot().render(<App />);
37
89
  ```
38
90
 
39
- `pnpm build` runs the Rust `native-build` and `@gtkx/cli#codegen` first (hard Turbo upstreams), so the first build compiles the addon and generates the `@gtkx/gi`/`@gtkx/jsx` binding stores before any TypeScript package builds.
91
+ This is the [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world) example, with `app.tsx` and `index.tsx` combined into a single snippet. `@gtkx/gi` and `@gtkx/jsx` are per-project bindings generated by the CLI, not packages you install from npm.
40
92
 
41
- ## Common commands
93
+ ## Why GTKX
42
94
 
43
- All root scripts run through Turbo over the workspace (the root meta-package is excluded with `--filter=!gtkx`).
95
+ ### A declarative layer for the GNOME stack
44
96
 
45
- | Command | Description |
46
- | --- | --- |
47
- | `pnpm build` | Build all workspace packages (runs codegen + native-build first). |
48
- | `pnpm --filter <pkg> dev` | Start a package/example dev server (hot-reloading `gtkx dev`); see [Running the examples](#running-the-examples). There is no root `dev` script. |
49
- | `pnpm test` | Run the Vitest workspace plus per-package test scripts. |
50
- | `pnpm typecheck` | Type-check every package via `tsc -b --emitDeclarationOnly` across the reference graph. |
51
- | `pnpm lint` | Full quality gate: ts-reference drift check, biome, knip (default + production), dependency-cruiser, plus per-package lint (Rust fmt/clippy on native). |
52
- | `pnpm codegen` | Generate/refresh the `.gtkx` GIR and JSX binding stores consumed by other packages. |
53
- | `pnpm coverage` | Aggregated v8 lcov coverage (TS) plus native Rust coverage. |
54
- | `pnpm sync:ts-refs` | Rewrite TypeScript project references from `package.json` deps and format them (add `--check` to fail on drift). |
55
- | `pnpm asan` / `pnpm miri` / `pnpm bench` | Native AddressSanitizer suite, Miri marshalling subset, and CodSpeed benchmarks under the headless compositor. |
56
- | `pnpm release` | Build, inject README into published packages, stage native artifacts, and publish to npm. |
57
- | `pnpm publish-test` | Publish to an ephemeral Verdaccio registry, then scaffold, build, typecheck, and test a consumer app end-to-end. |
97
+ GTK4 is mature, and GtkBuilder XML can lay out a static interface, but nothing re-renders that interface when your application state changes, and nothing hot-reloads it as you work. GTKX adds that missing layer, and the tooling around it, on top of the stack you already know:
58
98
 
59
- To run tests for a single package, filter through Turbo or pnpm, for example:
99
+ - a React reconciler that exposes every GObject as a JSX element,
100
+ - a CLI for scaffolding, development, and production builds,
101
+ - a dev server with Fast Refresh that patches your running UI in place,
102
+ - CSS-in-JS styling and high-level list, grid, and dialog components,
103
+ - a Testing Library-style API for querying and driving your widgets in tests,
104
+ - and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
60
105
 
61
- ```sh
62
- pnpm --filter @gtkx/ffi test
63
- pnpm --filter @gtkx/react test
64
- pnpm --filter @gtkx/cli build
65
- ```
106
+ ### The full GNOME API surface
66
107
 
67
- ## Running the examples
108
+ React Native and similar frameworks hide the native toolkit so one API can run everywhere. GTKX exposes it: GTK4, Adwaita, and any other GObject-Introspection library on your system. Linux-only by design.
68
109
 
69
- Each example exposes the standard `dev`, `build`, and `start` scripts that wrap the CLI (`gtkx dev` / `gtkx build` / `node dist/bundle.js`).
110
+ ### Why Node.js, and why generated bindings
70
111
 
71
- ```sh
72
- # Counter app demonstrating the basics
73
- pnpm --filter hello-world dev
112
+ GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [why-gtkx guide](https://gtkx.dev/guide/why-gtkx) covers the comparison in full.
74
113
 
75
- # Notes app from the tutorial (uses @gtkx/css and @gtkx/animate, GSettings via #data)
76
- pnpm --filter tutorial dev
114
+ GTKX generates the TypeScript types and the native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. Codegen covers the whole GTK4 and Adwaita surface.
77
115
 
78
- # GTK4 widget showcase (the React port of the official gtk-demo; the only example with tests)
79
- pnpm --filter gtk-demo dev
80
- pnpm --filter gtk-demo coverage
116
+ At runtime, the native Rust core calls straight into the system GTK4, Adwaita, and GLib libraries through libffi, without loading libgirepository at all.
81
117
 
82
- # Simple browser using WebKitWebView
83
- pnpm --filter browser dev
84
- ```
118
+ ## Quick start
85
119
 
86
- Build and run any example's production bundle:
120
+ GTKX is Linux-only and needs Node.js 24 or later. See [Requirements](#requirements).
121
+
122
+ Scaffold a new app with the `create-gtkx` initializer:
87
123
 
88
124
  ```sh
89
- pnpm --filter hello-world build
90
- pnpm --filter hello-world start
125
+ npm create gtkx@rc
91
126
  ```
92
127
 
93
- The tutorial additionally packages as a single executable (`pnpm --filter tutorial build:sea`) and as a Flatpak (`pnpm --filter tutorial build:flatpak`); these need esbuild, postject, and a Flatpak toolchain.
128
+ The same command works with other package managers: `pnpm create gtkx@rc` or `yarn create gtkx@rc`.
129
+
130
+ Then run your new app:
94
131
 
95
- ## Gotchas
132
+ ```sh
133
+ cd my-app
134
+ npm run dev
135
+ ```
96
136
 
97
- - **codegen and native-build come first.** A clean checkout cannot type-check or build any TypeScript package until the Rust addon is compiled and codegen has produced `.gtkx`; both are hard Turbo upstreams. `pnpm lint` first creates the `.gtkx` symlink that knip and dependency-cruiser resolve against.
98
- - **Generated packages are not hand-edited.** `@gtkx/gi`, `@gtkx/jsx`, and the generated `@gtkx/gl` sources come from `@gtkx/codegen`. Change the emitters or `gtkx.config.ts` and regenerate (`pnpm codegen`); the store swap is atomic, so partial writes never appear.
99
- - **GTK tests/benches need a headless display.** Running native `test`/`coverage`/`asan` or the GTK suites outside the headless wrapper fails to initialize a display; the harness provisions a Wayland compositor with software rendering. Native tests run single-threaded because GTK requires a single owning thread.
100
- - **The native runtime is single-use.** All GObject/GTK mutation runs only on the single `gtkx-glib` thread; native init is one-shot and quit is terminal, so a process cannot restart the runtime. Importing `@gtkx/ffi` starts the GLib main loop and registers a process exit handler.
101
- - **Project references track deps.** TypeScript references are generated from `package.json` dependency fields by `sync-ts-references`; hand-editing them is reported as drift by the `--check` run in lint. Change deps, then run `pnpm sync:ts-refs`.
102
- - **`@gtkx/testing` cleanup is not automatic.** Consumers must register `cleanup()` (the e2e setup wires it into `afterEach`/`afterAll`), or leaked windows persist across tests.
103
- - **The dev loop restarts via exit code 75.** The dev supervisor and runner signal restart intent purely through process exit code 75; Fast Refresh applies only to SSR-transformed project files where every export looks like a React component, otherwise the whole process restarts.
137
+ To go further, follow the [tutorial](https://gtkx.dev/tutorial/).
104
138
 
105
139
  ## Documentation
106
140
 
107
- Architecture and subsystem docs live under `docs/`:
141
+ The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tutorial that builds a complete GNOME app, from scaffolding to packaging and shipping, plus guides and a full API reference.
142
+
143
+ **[Read the docs &rarr;](https://gtkx.dev/guide/why-gtkx)**
144
+
145
+ ## Requirements
146
+
147
+ GTKX is Linux-only. You need:
148
+
149
+ - Linux with the GTK4 (4.20 or later), Adwaita (1.8 or later), and GLib development libraries
150
+ - Node.js 24 or later
151
+
152
+ The `@gtkx/native` addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
153
+
154
+ ## Examples
155
+
156
+ Explore the [example apps](https://github.com/gtkx-org/gtkx/tree/main/examples):
157
+
158
+ - [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world): the counter above.
159
+ - [`gtk-demo`](https://github.com/gtkx-org/gtkx/tree/main/examples/gtk-demo): a React port of the official GTK4 widget showcase, covering lists, dialogs, gestures, CSS, and OpenGL.
160
+ - [`browser`](https://github.com/gtkx-org/gtkx/tree/main/examples/browser): a WebKitWebView-based web browser.
161
+ - [`tutorial`](https://github.com/gtkx-org/gtkx/tree/main/examples/tutorial): the Tasks app the documentation builds.
162
+
163
+ ## Status
164
+
165
+ GTKX 1.0 is at the release candidate stage.
166
+
167
+ ## Contributing
168
+
169
+ Contributions are welcome. See [CONTRIBUTING.md](https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md), the [Code of Conduct](https://github.com/gtkx-org/gtkx/blob/main/CODE_OF_CONDUCT.md), and the [security policy](https://github.com/gtkx-org/gtkx/blob/main/SECURITY.md). Building the repo needs Node.js 24 or later, pnpm, and a Rust toolchain.
108
170
 
109
- - [`docs/architecture.md`](docs/architecture.md) — architecture overview and layer stack.
110
- - [`docs/rendering.md`](docs/rendering.md) — the render and event pipeline.
111
- - [`docs/codegen.md`](docs/codegen.md) — the GIR/Khronos code generator and the runtime contract.
112
- - [`docs/cli.md`](docs/cli.md) — the CLI and project workflow.
113
- - [`docs/styling.md`](docs/styling.md) — styling, animation, and GL.
114
- - [`docs/mcp.md`](docs/mcp.md) — the MCP server.
115
- - [`docs/testing.md`](docs/testing.md) — the testing architecture.
116
- - [`docs/build-system.md`](docs/build-system.md) — the build system and quality tooling.
171
+ ## License
117
172
 
118
- For an agent-oriented index of packages and the hard build rules, see [`CLAUDE.md`](CLAUDE.md).
173
+ GTKX is licensed under [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).