Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/devhammed/react-gtk/llms.txt

Use this file to discover all available pages before exploring further.

This tutorial will guide you through creating your first React GTK desktop application. You’ll learn how to set up a project, create components, and render a functional GTK window.
Before starting, make sure you have installed React GTK and all prerequisites (GJS, GTK 4.0, Node.js).

Create your first app

Let’s build a simple counter application to learn the basics of React GTK.
1

Set up the project

Create a new directory and initialize your project:
mkdir my-first-gtk-app
cd my-first-gtk-app
npm init -y
Install dependencies:
npm install react react-gtk-renderer
npm install -D typescript parcel @parcel/packager-ts @parcel/transformer-typescript-types
Create the project structure:
mkdir -p src/components
2

Configure TypeScript

Create tsconfig.json in the project root:
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020"],
    "jsx": "react",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "node"
  },
  "include": ["src/**/*"]
}
3

Create the app component

Create src/components/app.tsx with a simple counter:
src/components/app.tsx
import { useState } from 'react';
import {
  GtkWindow,
  GtkBox,
  GtkLabel,
  GtkButton,
  GtkAlign,
  GtkOrientation
} from 'react-gtk-renderer';

export function MyApp() {
  const [count, setCount] = useState(0);

  return (
    <GtkWindow
      defaultHeight={400}
      defaultWidth={600}
      title="My First GTK App"
    >
      <GtkBox
        orientation={GtkOrientation.VERTICAL}
        spacing={20}
        marginStart={40}
        marginEnd={40}
        marginTop={40}
        marginBottom={40}
        valign={GtkAlign.CENTER}
        halign={GtkAlign.CENTER}
      >
        <GtkLabel label="Welcome to React GTK!" />
        
        <GtkLabel label={`Count: ${count}`} />
        
        <GtkButton onClicked={() => setCount(count + 1)}>
          Click me!
        </GtkButton>
        
        <GtkButton onClicked={() => setCount(0)}>
          Reset
        </GtkButton>
      </GtkBox>
    </GtkWindow>
  );
}
Notice how you can use React hooks like useState - React GTK works with the full React API!
4

Create the entry point

Create src/index.tsx to initialize and render your app:
src/index.tsx
import { createRoot } from 'react-gtk-renderer';
import { MyApp } from './components/app';

declare const imports: any;

imports.package.init({
  name: 'com.example.myfirstapp',
  version: '1.0.0',
  prefix: '/usr',
  libdir: '/usr/lib',
  pkgdatadir: '/usr/share'
});

imports.package.run({
  main: function (argv: string[]) {
    const root = createRoot({
      id: 'com.example.myfirstapp'
    });

    root.render(<MyApp />, argv);
  }
});
The application ID (com.example.myfirstapp) should follow reverse-DNS notation. Use a unique identifier for your app.
5

Add build scripts

Update your package.json to include build and run scripts:
package.json
{
  "name": "my-first-gtk-app",
  "version": "1.0.0",
  "source": "src/index.tsx",
  "scripts": {
    "build": "parcel build --no-source-maps",
    "start": "parcel watch --no-source-maps --no-hmr",
    "app": "gjs dist/index.js",
    "dev": "npm run build && npm run app",
    "clean": "rm -rf dist .parcel-cache"
  }
}
6

Build and run

Build your application and run it:
npm run build
npm run app
You should see a GTK window with:
  • A welcome message
  • A counter display
  • Two buttons to increment and reset the counter
Congratulations! You’ve built your first React GTK application!

Understanding the code

Let’s break down the key parts of your first application:

Creating a root

const root = createRoot({ id: 'com.example.myfirstapp' });
The createRoot function initializes your GTK application. It returns a RootAppInstance that you use to render your React components.

GTK components

<GtkWindow defaultHeight={400} defaultWidth={600} title="My First GTK App">
  {/* Window content */}
</GtkWindow>
GTK widgets are available as React components. Each component accepts props that map to GTK widget properties.

Layout with GtkBox

<GtkBox
  orientation={GtkOrientation.VERTICAL}
  spacing={20}
  valign={GtkAlign.CENTER}
  halign={GtkAlign.CENTER}
>
  {/* Child widgets */}
</GtkBox>
GtkBox is a container widget for laying out child widgets horizontally or vertically. Use it to create structured layouts.

Event handling

<GtkButton onClicked={() => setCount(count + 1)}>
  Click me!
</GtkButton>
GTK signals (events) are exposed as props with the on prefix. The clicked signal becomes onClicked.

React hooks

const [count, setCount] = useState(0);
You can use all React hooks and patterns. State updates trigger re-renders, and the React GTK reconciler efficiently updates the GTK widget tree.

Add more features

Now that you have a basic app, try adding these features:

Text input

Add a GtkEntry component for text input:
const [text, setText] = useState('');

<GtkEntry
  onChanged={(entry) => setText(entry.text)}
/>

Multiple pages

Use GtkStack and GtkStackPage to create multi-page layouts:
<GtkStack>
  <GtkStackPage name="page1">
    {/* First page */}
  </GtkStackPage>
  <GtkStackPage name="page2">
    {/* Second page */}
  </GtkStackPage>
</GtkStack>

Refs

Access GTK widget instances with refs:
const entryRef = useRef<GtkEntryImpl>();

<GtkEntry ref={entryRef} />

// Access widget: entryRef.current

Styled text

Apply Pango attributes for text formatting:
<GtkEntry
  attributes={[
    {
      start: 0,
      end: 5,
      type: 'foreground',
      value: 'red'
    }
  ]}
/>

Development workflow

For an efficient development workflow:

Watch mode

Use watch mode to automatically rebuild on file changes:
npm run start
In another terminal, run your app:
npm run app
Restart the app after each rebuild to see your changes.

Clean builds

If you encounter build issues, clean the cache:
npm run clean
npm run build

Debugging

View console output from your app:
console.log('Debug info:', someValue);
The output appears in the terminal where you run npm run app.
Use console.log to debug event handlers, state updates, and widget properties.

Complete example

Here’s a more complete example with multiple features:
src/components/app.tsx
import { useState, useRef } from 'react';
import {
  GtkWindow,
  GtkBox,
  GtkLabel,
  GtkButton,
  GtkEntry,
  GtkEntryImpl,
  GtkAlign,
  GtkOrientation
} from 'react-gtk-renderer';

export function MyApp() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');
  const entryRef = useRef<GtkEntryImpl>();

  const handleReset = () => {
    setCount(0);
    setName('');
    if (entryRef.current) {
      entryRef.current.buffer.text = '';
    }
  };

  return (
    <GtkWindow
      defaultHeight={500}
      defaultWidth={600}
      title="Counter & Greeter"
    >
      <GtkBox
        orientation={GtkOrientation.VERTICAL}
        spacing={20}
        marginStart={40}
        marginEnd={40}
        marginTop={40}
        marginBottom={40}
        valign={GtkAlign.CENTER}
        halign={GtkAlign.CENTER}
      >
        <GtkLabel label="Welcome to React GTK!" />
        
        {/* Counter section */}
        <GtkBox
          orientation={GtkOrientation.VERTICAL}
          spacing={10}
          halign={GtkAlign.CENTER}
        >
          <GtkLabel label={`You clicked ${count} times`} />
          <GtkButton onClicked={() => setCount(count + 1)}>
            Increment
          </GtkButton>
        </GtkBox>
        
        {/* Greeter section */}
        <GtkBox
          orientation={GtkOrientation.VERTICAL}
          spacing={10}
          halign={GtkAlign.CENTER}
        >
          <GtkEntry
            ref={entryRef}
            onChanged={(entry) => setName(entry.text)}
          />
          {name && <GtkLabel label={`Hello, ${name}!`} />}
        </GtkBox>
        
        {/* Reset button */}
        <GtkButton onClicked={handleReset}>
          Reset All
        </GtkButton>
      </GtkBox>
    </GtkWindow>
  );
}

Next steps

Now that you’ve built your first React GTK app, explore these topics:

Core concepts

Learn how React GTK’s rendering and reconciliation works

GTK widgets

Explore all available GTK components and their properties

Event handling

Master GTK signals and event handling in React

Working with refs

Access GTK widget instances and use the imperative API

Building apps

Learn best practices for structuring production applications

Examples

See more complete example applications
Need help? Check out the API reference for detailed documentation on all components and APIs.

Build docs developers (and LLMs) love