Guidelines for developing GNOME Shell extensions with modern JavaScript, focusing on panel indicators, timers, and UI components using GJS (GNOME JavaScript bindings).
Expert guidance for building GNOME Shell extensions using GJS (GNOME JavaScript bindings) with modern ES2022+ syntax.
Extensions should follow this standard layout:
```
extension/
├── metadata.json # Extension metadata (uuid, shell-version, etc.)
├── extension.js # Main entry point (init, enable, disable)
├── stylesheet.css # Optional styling
└── *.js # Additional modules
```
Required fields:
Must export three functions:
```javascript
function init() {
// Initialize extension (runs once on load)
}
function enable() {
// Enable extension (add UI elements, start timers, etc.)
}
function disable() {
// Disable extension (clean up resources, remove UI)
}
```
Use `PanelMenu.Button` for top bar widgets:
```javascript
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
import St from 'gi://St';
const indicator = new PanelMenu.Button(0.0, 'My Extension', false);
const label = new St.Label({ text: '🍅', y_align: Clutter.ActorAlign.CENTER });
indicator.add_child(label);
// Add to panel
Main.panel.addToStatusArea('my-extension', indicator);
```
Use `GLib.timeout_add_seconds` for periodic updates:
```javascript
import GLib from 'gi://GLib';
let timerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
// Update logic here
return GLib.SOURCE_CONTINUE; // Keep running
});
// Clean up in disable()
if (timerId) {
GLib.Source.remove(timerId);
timerId = null;
}
```
```javascript
import St from 'gi://St'; // Shell Toolkit (UI widgets)
import GLib from 'gi://GLib'; // Core utilities, timers
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
```
Standard installation path:
```bash
~/.local/share/gnome-shell/extensions/<uuid>/
```
After installation, restart GNOME Shell (X11: `Alt+F2`, `r`; Wayland: log out/in) or use Extensions app.
1. Edit files in `extension/` directory
2. Run linter: `npm run lint` or custom `lint.sh`
3. Install extension: copy to `~/.local/share/gnome-shell/extensions/<uuid>/`
4. Restart GNOME Shell or re-enable extension
5. Check logs: `journalctl -f -o cat /usr/bin/gnome-shell`
```javascript
let label;
let timerId;
function enable() {
label = new St.Label({ text: '⏱️' });
indicator.add_child(label);
timerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
label.set_text(getCurrentStatus());
return GLib.SOURCE_CONTINUE;
});
}
function disable() {
if (timerId) GLib.Source.remove(timerId);
if (label) label.destroy();
}
```
```javascript
indicator.connect('button-press-event', () => {
// Handle click
return Clutter.EVENT_PROPAGATE;
});
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/gnome-shell-extension-development/raw