Skip to content

Intro

This tutorial will walk you through creating a Gtk4 application from scratch using Gnim. Before jumping in, you are expected to know TypeScript or at least JavaScript.

JavaScript Runtime

The JavaScript runtime that Gnim uses is GJS. It is built on Firefox's SpiderMonkey JavaScript engine and the GNOME platform libraries.

IMPORTANT

GJS is not Node, not Deno, and not Bun. GJS does not implement some common Web APIs you might be used to from these other runtimes such as fetch. The standard library of GJS comes from GLib, Gio and GObject which are libraries written in C and exposed to GJS through FFI using GObject Introspection

Installing system dependencies

You will need the following dependencies installed:

  • gjs
  • gtk4
  • JavaScript package manager of your choice
sh
sudo pacman -Syu gjs gtk4 npm
sh
sudo dnf install gjs-devel gtk4-devel npm
sh
sudo apt install libgjs-dev libgtk-4-dev npm
nix
{
  inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";

  outputs = {
    self,
    nixpkgs,
  }: let
    forAllSystems = nixpkgs.lib.genAttrs ["x86_64-linux" "aarch64-linux"];
  in {
    devShells = forAllSystems (system: let
      pkgs = nixpkgs.legacyPackages.${system};
    in {
      # enter this shell using `nix develop`
      default = pkgs.mkShell {
        packages = with pkgs; [
          gobject-introspection
          glib
          nodePackages.npm
          gtk4
          gjs
        ];
      };
    });
  };
}

Using a template

sh
npm create gnim@alpha
sh
pnpm create gnim@alpha
sh
yarn create gnim@alpha
sh
bun create gnim@alpha
sh
deno init --npm gnim@alpha

Creating a new project manually

  1. Create a project directory and install Gnim

    sh
    mkdir gnim-app
    cd gnim-app
    npm install gnim@alpha @gnim-js/gtk4@alpha
  2. Configure tsconfig.json

    json
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "target": "ES2022",
        "module": "ES2022",
        "lib": ["ES2024"],
        "outDir": "dist",
        "strict": true,
        "moduleResolution": "Bundler",
        "skipLibCheck": true,
        "jsx": "react-jsx",
        "jsxImportSource": "gnim",
        "typeRoots": ["./.gnim/types"]
      },
      "include": ["./src/**/*"]
    }
  3. Add scripts to package.json

json
{
  "scripts": {
    "types": "gnim types",
    "dev": "gnim dev src/main.tsx"
  }
}
  1. Generate types

    sh
    npm run types

    TIP

    Make sure to ignore generated files.

    sh
    echo ".gnim/" > .gitignore
  2. Create the entry point

    tsx
    // src/main.tsx
    import Gtk from "gi://Gtk?version=4.0"
    import { render } from "@gnim-js/gtk4"
    
    function App() {
      return <Gtk.Window visible>hello</Gtk.Window>
    }
    
    const app = new Gtk.Application()
    app.connect("activate", () => {
      const dispose = render(App, app)
      app.connect("shutdown", dispose)
    })
    app.runAsync(null)
  3. Start the dev server

    sh
    npm run dev