The Problem
You've built a beautiful shell. Your friends want it. But copying QML files doesn't include dependencies, fonts, icons, and configuration. A proper package ensures everything works out of the box.
The Naive Approach
Zip up the config directory:
bash
zip -r my-shell.zip ~/.config/quickshell/The recipient has to manually install Quickshell, unzip to the right place, and figure out missing dependencies. This approach fails for non-technical users.
Mental Model
Think of packaging like meal kit delivery. Instead of sending the customer a grocery list and recipe (manual install), you send a box with pre-portioned ingredients and step-by-step pictures (package). The meal kit ensures consistent results.
Package Structure
my-shell/
quickshell/
shell.qml
config.json
components/
services/
fonts/
README.md
LICENSE
setup.shDistribution Methods
1. Manual Installation Script
bash
#!/bin/bash
# setup.sh
set -euo pipefail
# Check dependencies
command -v quickshell >/dev/null 2>&1 || { echo "Quickshell not installed. Install it first."; exit 1; }
# Create config directory
mkdir -p "$HOME/.config/quickshell"
# Copy configuration
cp -r quickshell/* "$HOME/.config/quickshell/"
# Install fonts
if [ -d "fonts" ]; then
mkdir -p "$HOME/.local/share/fonts"
cp fonts/* "$HOME/.local/share/fonts/"
fc-cache -f
fi
# Copy desktop entry for display managers
mkdir -p "$HOME/.local/share/wayland-sessions"
cp quickshell.desktop "$HOME/.local/share/wayland-sessions/"
echo "Installation complete! Select 'MyShell' from your display manager."2. Desktop Entry (Display Manager Integration)
ini
# my-shell.desktop
[Desktop Entry]
Name=My Shell
Comment=A custom Quickshell desktop environment
Exec=quickshell -c ~/.config/quickshell/shell.qml
Type=Application
DesktopNames=quickshell3. Arch Linux (AUR Package)
bash
# PKGBUILD
pkgname=quickshell-my-shell
pkgver=1.0.0
pkgrel=1
arch=('any')
depends=('quickshell')
source=("https://github.com/user/my-shell/archive/v$pkgver.tar.gz")
package() {
install -Dm644 quickshell/shell.qml "$pkgdir/usr/share/quickshell-shells/my-shell/shell.qml"
install -Dm644 quickshell.desktop "$pkgdir/usr/share/wayland-sessions/my-shell.desktop"
install -Dm644 README.md "$pkgdir/usr/share/doc/my-shell/README.md"
}4. Nix Flake
nix
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
quickshell.url = "github.com/outfoxxed/quickshell";
};
outputs = { self, nixpkgs, quickshell }: let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in {
packages.${system}.my-shell = pkgs.stdenv.mkDerivation {
name = "my-shell";
src = ./.;
installPhase = ''
mkdir -p $out/share/quickshell-shells/my-shell
cp -r quickshell/* $out/share/quickshell-shells/my-shell/
mkdir -p $out/share/wayland-sessions
cp my-shell.desktop $out/share/wayland-sessions/
'';
};
};
}Dependency Management
Declare dependencies clearly:
json
// metadata.json
{
"name": "my-shell",
"version": "1.0.0",
"quickshell": ">=0.3.0",
"dependencies": {
"system": ["swww", "pipewire", "bluez"],
"fonts": ["JetBrainsMono Nerd Font", "Font Awesome 6"],
"qt": ["qt6-base", "qt6-wayland", "qt6-svg"]
}
}Versioning
Follow semver for your shell:
- Patch: Bug fixes, minor styling changes
- Minor: New features, new panels, backward compatible
- Major: Breaking changes, config format changes
bash
git tag v1.2.3
git push origin v1.2.3Exercises
⭐Exercise
Create a `setup.sh` script for your shell. Test it on a fresh install. Ensure all dependencies are checked before copying files.
⭐⭐Exercise
Package your shell for the AUR. Create a `PKGBUILD` that installs to `/usr/share/quickshell-shells/`. Submit to the AUR.
⭐⭐⭐Exercise
Create a Nix flake for your shell. Ensure it builds with `nix build`. Add an overlay so users can install with `nix profile install`.
What You've Learned
- Provide a setup.sh script that checks dependencies and copies files
- Create a .desktop entry for display manager integration
- Package for distribution-specific formats (AUR, Nix)
- Declare dependencies in metadata.json with version constraints