JustToThePoint English Website Version
JustToThePoint en español

Arch Linux Post-Installation: Audio with PipeWire and Development Tools

Sometimes people don’t want to hear the truth because they don’t want their illusions destroyed, Friedrich Nietzsche.

image info

Introduction

With the core system settings and remote access configured in the previous steps, we now turn our attention to multimedia capabilities and establishing a productive development environment. This section combines two essential post-installation scripts: 09-audio.sh and 10-development.sh.

First, we transition from the legacy PulseAudio server to PipeWire, the modern standard for audio and video routing on Linux. The script handles the removal of conflicting packages, installs the necessary compatibility layers (for PulseAudio, ALSA, and JACK), and configures Bluetooth support. Crucially, it sets up PipeWire as a user service, ensuring that audio permissions and processes are handled correctly within your specific user session rather than at the system level.

Next, we build a robust toolkit for developers. This includes installing the Hugo static site generator (extended edition), setting up Visual Studio Code via the AUR to ensure access to the proprietary marketplace, and configuring a Python environment with pipx for isolated tool management. Whether you are coding, writing, or managing servers, these tools form the backbone of a functional Arch Linux workstation.

PipeWire Audio Stack Setup

#!/usr/bin/env bash
# ── 09-audio.sh ───────────────────────────────────────────────────────────────
#   Installs and configures the PipeWire audio/video routing daemon as a
#   complete replacement for PulseAudio and JACK. Enables low-latency
#   professional audio, Bluetooth codecs, and seamless application compatibility.
#
# Architecture:
#   pipewire         — Core daemon handling audio/video streams and routing
#   wireplumber      — Session/policy manager (controls which app gets audio)
#   pipewire-pulse   — PulseAudio compatibility layer
#   pipewire-alsa    — ALSA compatibility layer
#   pipewire-jack    — JACK compatibility layer
#
# Why PipeWire replaces both PulseAudio AND JACK:
#   Unified stack — PipeWire handles consumer and pro audio simultaneously with
#   one daemon, lower latency, and better Wayland/Bluetooth support.
#
# Run: bash 09-audio.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail # Strict mode

echo "── 09-audio: installing PipeWire stack..."

# ── Remove conflicting audio servers ──────────────────────────────────────────
# PulseAudio and PipeWire cannot run simultaneously.
# On a fresh Arch install this is unlikely, but worth checking.
for pkg in pulseaudio pulseaudio-bluetooth pulseaudio-alsa jack2; do
  if pacman -Qi "$pkg" &>/dev/null; then
    echo "  ⚠️  Removing conflicting package: $pkg"
    sudo pacman -R --noconfirm "$pkg"
  fi
done

# ── Install PipeWire and dependencies ────────────────────────────────────────────────────
# IMPORTANT: inline comments (#) cannot appear after package names on the
# same line inside a pacman -S call — the shell passes them as package names.
# Always put comments on separate lines or use an array.
sudo pacman -S --needed --noconfirm \
  pipewire \
  pipewire-alsa \
  pipewire-pulse \
  pipewire-jack \
  wireplumber \
  pavucontrol \
  playerctl \
  pamixer

# ── Bluetooth audio ───────────────────────────────────────────────────────────
# Same rule applies: comments must be on separate lines.
sudo pacman -S --needed --noconfirm \
  bluez \
  bluez-utils \
  blueman

sudo systemctl enable bluetooth

# ── Enable PipeWire as user services ─────────────────────────────────────────
# PipeWire runs as user services (not system service) — one instance per user.
# systemctl --user manages services that run in the user's login session.
#
# Why user services instead of system services:
#   Audio is per-user. Running PipeWire as a system service would mean all
#   users share one audio daemon, which causes permission conflicts.
#   The user service is started automatically at login.
systemctl --user enable pipewire
systemctl --user enable pipewire-pulse
systemctl --user enable wireplumber

# Start immediately if we're already in a graphical user session.
# The 2>/dev/null suppresses "Failed to connect to bus" errors that appear
# when this script runs from a TTY before a user session is active.
systemctl --user start pipewire       2>/dev/null || echo "  ℹ️   pipewire: will start after next login"
systemctl --user start pipewire-pulse 2>/dev/null || echo "  ℹ️   pipewire-pulse: will start after next login"
systemctl --user start wireplumber    2>/dev/null || echo "  ℹ️   wireplumber: will start after next login"

# ── Verify PipeWires installation───────────────────────────────────────────────────────
echo
echo "── PipeWire status:"
if pactl info 2>/dev/null | grep -q "PipeWire"; then
  # If pactl is talking to a PipeWire-backed PulseAudio server, pactl info will contain something like:
  # Server Name: PulseAudio (on PipeWire 1.0.5)
  echo "  ✅  PipeWire is running as PulseAudio replacement"
  pactl info | grep "Server Name"
else
  echo "  ⚠️  PipeWire not yet running — will start after next login"
fi

echo "── Audio sinks (output devices):"
pactl list short sinks 2>/dev/null || echo "  (available after next login)"
# This prints the available output devices, or a fallback message if pactl can’t talk to the server.
echo
echo "✅  09-audio: done"
echo "    Next: bash 10-development.sh"

Development Tools Setup

#!/usr/bin/env bash
# ── 10-development.sh ─────────────────────────────────────────────────────────
# Install development tools: Hugo (static site generator), VS Code with essential extensions,
# Python, and VS Code extensions.
# Run: bash 10-development.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

echo "── 10-development: installing development tools..."

# ── Hugo (static site generator) ─────────────────────────────────────────────
# Hugo is available in the official Arch repos.
echo "── Installing Hugo..."
sudo pacman -S --needed --noconfirm hugo

echo "  ✅  Hugo: $(hugo version | head -1)"

# ── VS Code (via AUR) ─────────────────────────────────────────────────────────
# visual-studio-code-bin is the official Microsoft binary from the AUR.
# It includes the proprietary marketplace (GitHub Copilot, Remote-SSH, etc.).
#
echo "── Installing VS Code (visual-studio-code-bin)..."
paru -S --needed --noconfirm visual-studio-code-bin

echo "  ✅  VS Code: $(code --version | head -1)"

# ── VS Code extensions ────────────────────────────────────────────────────────
# Installed via `code --install-extension `.
# Extensions are installed to ~/.vscode/extensions/ by default.
# Reference: https://marketplace.visualstudio.com/vscode
#
echo "── Installing VS Code extensions..."

EXTENSIONS=(
  # ── Python ────────────────────────────────────────────────────────────────
  ms-python.python                    # Python language support + debugger
  ms-python.pylance                   # Fast Python language server
  ms-python.black-formatter           # Black auto-formatter
  charliermarsh.ruff                  # Ruff linter (fast Python linter in Rust)

  # ── Remote development ────────────────────────────────────────────────────
  ms-vscode-remote.remote-ssh         # SSH into your server
  ms-vscode-remote.remote-containers  # Dev containers support

  # ── Writing / docs ────────────────────────────────────────────────────────
  yzhang.markdown-all-in-one          # Markdown preview, shortcuts, TOC
  streetsidesoftware.code-spell-checker  # Spell checker for code and docs
  esbenp.prettier-vscode              # Prettier formatter (JS/HTML/CSS/YAML)

  # ── Appearance ────────────────────────────────────────────────────────────
  dracula-theme.theme-dracula         # Dracula colour theme
  pkief.material-icon-theme           # File icons

  # ── Web / Hugo ────────────────────────────────────────────────────────────
  budparr.language-hugo-vscode        # Hugo template syntax highlighting
  tamasfe.even-better-toml            # TOML support (Hugo config files)

  # ── Nix ───────────────────────────────────────────────────────────────────
  jnoortheen.nix-ide                  # Nix language support + formatting

  # ── Git ───────────────────────────────────────────────────────────────────
  eamodio.gitlens                     # Git blame, history, and visualisation
)

INSTALLED=0
FAILED=0
for ext in "${EXTENSIONS[@]}"; do
  # Skip comment lines (lines starting with #)
  [[ "$ext" =~ ^# ]] && continue
  [[ -z "$ext" ]] && continue

  if code --install-extension "$ext" --force 2>/dev/null; then
    echo "  ✅  $ext"
    (( INSTALLED++ )) || true
  else
    echo "  ⚠️  Failed: $ext"
    (( FAILED++ )) || true
  fi
done

echo "  Extensions: $INSTALLED installed, $FAILED failed"

# ── Python ────────────────────────────────────────────────────────────────────
echo "── Installing Python tools..."
sudo pacman -S --needed --noconfirm \
  python \
  python-pip \
  python-pipx \
  python-virtualenv

echo "Sometimes, you need to install pip inside the venv"
echo "Activate the venv, then run: python -m ensurepip --upgrade"

# Install commonly used Python CLI tools via pipx (isolated, no venv needed)
# pipx installs each tool in its own venv but exposes the binary globally
pipx install poetry    2>/dev/null || true   # dependency manager
pipx install httpie    2>/dev/null || true   # HTTPie (http CLI client)
pipx install buku      2>/dev/null || true   # A bookmark manager

echo "  ✅  Python $(python3 --version)"

# ── Node.js (for some VS Code extensions and web tools) ──────────────────────
echo "── Installing Node.js..."
sudo pacman -S --needed --noconfirm \
  nodejs    \
  npm

echo "  ✅  Node.js $(node --version)"

echo
echo "✅  10-development: done"
echo "    Next: bash 11-dotfiles.sh"
Bitcoin donation

JustToThePoint Copyright © 2011 - 2026 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.