This extension uses a modern TypeScript-based development workflow with Bun and automated build scripts. The recommended setup involves:
- Host machine: Edit code, run linting/formatting, and manage versions
- VM environment: Test the extension in a controlled GNOME session
- Automated scripts: Handle building, installation, VM setup, and development workflow
- Host: Bun, OpenSSH client
- VM: Linux distribution with GNOME and Wayland (I use Fedora)
The project includes several automation scripts in the scripts/ directory:
Fun fact: the build uses esbuild-preserve-whitespace, a plugin I made because I couldn't find an existing solution that keeps whitespace intact when transpiling GNOME Shell extensions. It's on npm if you need it! ☝️🤓
Handles the complete build process:
- Compiles TypeScript files using esbuild
- Compiles GResource files and translations
- Creates the
.shell-extension.zippackage - Supports installation, GDM restart, and unsafe reload (legacy)
Monitors GNOME Shell logs for debugging:
- Captures logs from both
gnome-shellandgjsprocesses - Supports filtered output showing only extension-related logs
- Automatically extracts extension name from
metadata.json
Automates VM setup for development:
- Generates
dev-{project}.shscript for SSHFS mounting and VM access - Copies development script to VM
- Installs
sshfsand creates mount points - Sets up proper permissions and SSHFS mounting
Launches a development GNOME Shell session using dbus-run-session:
- Uses
--devkit --waylandon GNOME 49+ - Falls back to
--nested --waylandon older versions
Automatically updates contributors in the About page:
- Fetches contributors from git history
- Updates the credits section with GitHub links
- Maintains contributor information dynamically
Handles version bumping and releases:
- Updates
package.jsonandmetadata.jsonversions - Creates git commits and tags
- Supports semantic versioning
Install Dependencies:
bun install # Install all dependenciesCode Quality Tools:
bun format # Format code with Biome
bun lint # Lint with safe fixes
bun lint:fix # Lint with unsafe fixes
bun check # Combined lint + format check
bun check:types # TypeScript type checking onlyVersion Management:
bun bump 1.5.0 # Bump version to 1.5.0
bun release 1.5.0 # Bump version, commit, and create git tagUpdate Contributors:
bun update-credits # Update contributor list from git historyInitial VM Configuration:
-
Install Fedora 41+ and log in
-
Enable auto-login so the session restarts automatically after GDM reloads:
GUI method: Settings → Users → Automatic Login (ON)
Manual method: edit
/etc/gdm/custom.confand add to the[daemon]section:[daemon] AutomaticLoginEnable=True AutomaticLogin=your-username
-
Install required tools:
sudo dnf install -y fuse-sshfs gnome-extensions-app jq
-
Install Bun:
curl -fsSL https://bun.sh/install | bash -
Set up autostart for convenient development:
- Add GNOME Extensions (
org.gnome.Extensions.desktop) to autostart - Add a Terminal to autostart
- Add GNOME Extensions (
Bootstrap VM environment from Host:
bun setup -- user@vm-ip # Generate dev script, copy to VM, install sshfsRun generated script in VM:
~/dev-vicinae-gnome-extension.sh # Mount host directory via SSHFS and start shellOnce mounted, you are in the project directory at /mnt/host/vicinae-gnome-extension with an interactive shell.
Build and Install (GNOME 49+ Wayland):
bun build # Build extension package only
bun build:install # Build and install extension
bun build:install:gdm # Build, install, then restart GDM to reload (auto-login required)Build and Install (Xorg / old workflow):
bun dev # Build, install, and unsafe-reload (Xorg only, legacy)
bun dev:nested # Build, install, and start nested Wayland sessionDebugging:
bun log # Monitor extension logs (filtered)
bun log:all # Monitor all GNOME Shell logs- Edit code on the host
- On the VM, ensure the SSHFS mount is active (
~/dev-vicinae-gnome-extension.sh) - In the mounted directory on the VM:
bun build:install:gdm
- GDM restarts → VM auto-logs back in → extension is installed and active
- Check logs:
bun log
src/: TypeScript source filesdist/: Compiled JavaScript (auto-generated)build/: Build artifacts and packages (gitignored)scripts/: Development automation scriptsdata/: Static resources (icons, UI files)
- Build artifacts are automatically placed in
build/directory - The
dist/directory contains compiled JavaScript when using TypeScript - Biome handles all linting and formatting;
dist/is gitignored - Generated
scripts/dev-*.shfiles are gitignored — each developer/environment generates their own viabun setup - GDM restart (
systemctl restart gdm) logs out the session — ensure auto-login is enabled in the VM so the session comes back without manual login