js-gnome-apps

GNOME JavaScript (GJS) Application Development

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "js-gnome-apps" with this command: npx skills add padparadscho/skills/padparadscho-skills-js-gnome-apps

GNOME JavaScript (GJS) Application Development

Technology Stack

Component Purpose

GJS JavaScript runtime (SpiderMonkey) with GObject Introspection bindings

GTK 4 UI toolkit

Libadwaita (Adw) 1.x GNOME-specific widgets, adaptive layouts, styling

GLib / GIO Core utilities, async I/O, settings, D-Bus, file operations

Meson Build system

Flatpak App packaging and distribution

Blueprint (optional) Declarative UI markup that compiles to GTK XML

Imports (ES Modules — required for new code)

// Built-in GJS modules import Cairo from "cairo"; import Gettext from "gettext"; import System from "system";

// Platform libraries via gi:// URI import GLib from "gi://GLib"; import GObject from "gi://GObject"; import Gio from "gi://Gio";

// Versioned imports (required when multiple API versions exist) import Gtk from "gi://Gtk?version=4.0"; import Adw from "gi://Adw?version=1";

// Relative user modules (include .js extension) import * as Utils from "./lib/utils.js";

Keep imports grouped: built-in → platform (gi:// ) → local, separated by blank lines. Use PascalCase for imported modules.

GObject Subclassing

Register every GObject subclass with GObject.registerClass() . Use constructor() (not _init() , which is legacy pre-GNOME 42).

const MyWidget = GObject.registerClass( { GTypeName: "MyWidget", Template: "resource:///com/example/MyApp/my-widget.ui", InternalChildren: ["title_label", "action_button"], Properties: { "example-prop": GObject.ParamSpec.string( "example-prop", "", "", GObject.ParamFlags.READWRITE, null, ), }, Signals: { "item-selected": { param_types: [GObject.TYPE_STRING], }, }, }, class MyWidget extends Gtk.Box { constructor(params = {}) { super(params); // Template children: this._title_label, this._action_button }

get example_prop() {
  return this._example_prop ?? null;
}

set example_prop(value) {
  if (this.example_prop === value) return;
  this._example_prop = value;
  this.notify("example-prop");
}

}, );

Key rules:

  • Property names: kebab-case in GObject declarations, snake_case in JS accessors

  • Always call this.notify('prop-name') in setters to emit change notifications

  • GTypeName is optional unless the type is referenced in UI XML <template class="...">

  • InternalChildren maps id attrs in UI XML → this._childId ; Children → this.childId

Application Entry Point

import GLib from "gi://GLib"; import GObject from "gi://GObject"; import Gio from "gi://Gio"; import Gtk from "gi://Gtk?version=4.0"; import Adw from "gi://Adw?version=1";

import { MyAppWindow } from "./window.js";

const MyApp = GObject.registerClass( class MyApp extends Adw.Application { constructor() { super({ application_id: "com.example.MyApp", flags: Gio.ApplicationFlags.DEFAULT_FLAGS, });

  const quitAction = new Gio.SimpleAction({ name: "quit" });
  quitAction.connect("activate", () => this.quit());
  this.add_action(quitAction);
  this.set_accels_for_action("app.quit", ["&#x3C;Primary>q"]);
}

vfunc_activate() {
  let win = this.active_window;
  if (!win) win = new MyAppWindow(this);
  win.present();
}

}, );

const app = new MyApp(); app.run([System.programInvocationName, ...ARGV]);

Async with Gio._promisify

Wrap _async/_finish pairs once at module level for async/await usage:

Gio._promisify( Gio.File.prototype, "load_contents_async", "load_contents_finish", );

const file = Gio.File.new_for_path("/tmp/example.txt"); try { const [contents] = await file.load_contents_async(null); const text = new TextDecoder().decode(contents); } catch (e) { logError(e, "Failed to load file"); }

Code Style (GJS conventions)

  • 4-space indentation, single quotes, semicolons

  • const by default, let when mutation needed, never var

  • File names: lowerCamelCase.js ; directories: lowercase

  • Arrow functions for inline callbacks; .bind(this) for method references

  • export for public API, never var

Reference Files

Consult these based on the task at hand:

  • Project setup & packaging: references/project-setup.md — Meson build, Flatpak manifests, GResource, application ID, desktop files, GSettings schemas, directory layout

  • UI design (GTK4 + Libadwaita): references/ui-patterns.md — Widget templates (UI XML), adaptive layouts (breakpoints, split views, view switcher), boxed lists, style classes, header bars, GNOME HIG patterns

  • GIO & platform patterns: references/gio-patterns.md — File I/O, GSettings, actions & menus, D-Bus, subprocesses, list models, GVariant

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

rs-ratatui-crate

No summary provided by upstream source.

Repository SourceNeeds Review
General

js-gnome-extensions

No summary provided by upstream source.

Repository SourceNeeds Review
General

rs-soroban-sdk

No summary provided by upstream source.

Repository SourceNeeds Review
General

js-stellar-sdk

No summary provided by upstream source.

Repository SourceNeeds Review