Mi guía de instalación de Arch Linux y Hyprland

#archlinux#hyprland#unix

Antes de empezar, un pequeño disclaimer:

Esto empezó siendo una guía donde me explicaba a mí mismo cómo instalar Arch Linux y Hyprland con la configuración que tengo. La escribí en 2024, la dejé a medias (el título llevó un “[incompleto]” durante dos años, para qué engañarnos), y en 2026 por fin la he completado y actualizado con el setup que uso a diario.

El motivo sigue siendo el mismo: llevo años usando Arch con Hyprland como daily driver, le he puesto tiempo y dedicación a una configuración que me gusta, y voy olvidando poco a poco qué y cómo lo configuré. Esta guía es un salvavidas por si algún día tengo que reinstalar desde cero. La publico porque espero que te ayude a ti también.

Una cosa importante sobre cómo está escrita: no quiero que copies mi configuración. Quiero que llegues a un escritorio completo entendiendo qué necesidad cubre cada pieza, veas cuál es mi elección y por qué, y elijas la tuya. Donde haya caminos alternativos razonables, te los dejo señalados.

En cada apartado listaré fuentes y recursos que he usado, por si te sirven. La mayoría están en inglés.

instalación de arch linux

Doy por hecho que ya tienes un USB booteable de Arch Linux, que se hace fácilmente con balena etcher, rufus o dd. También doy por hecho que tu equipo arranca con EFI.

Si prefieres saltarte toda esta sección, existe archinstall, el instalador guiado que viene en la propia ISO. Es un camino perfectamente válido y cada vez más gente lo usa. Yo prefiero la instalación manual porque haciéndola entiendes qué piezas componen tu sistema, y cuando algo se rompa (en Arch es un cuando, no un si) sabrás por dónde empezar a mirar.

Arrancamos desde el USB y preparamos teclado y fuente:

loadkeys es
setfont ter-132b

Compruebo la conexión a internet con:

ping -c 1 archlinux.org

Por ethernet no deberías tener problemas de conexión. Si es por wifi, es normal que no tengas internet porque no está conectado; para conectar, usa iwctl:

iwctl
# dentro de la consola de iwctl
device list
station NOMBRE_INTERFACE scan
station NOMBRE_INTERFACE get-networks
station NOMBRE_INTERFACE connect SSID
exit

Ahora vamos a ponernos en hora:

timedatectl set-timezone Europe/Madrid
timedatectl set-ntp true

particiones y formateo

Esto va a depender de tu disco y de cómo quieras instalar. Hay quien separa root y home en particiones diferentes; yo no le he visto ventaja para un equipo personal, así que lo hago simple con 3 particiones: EFI, swap y root.

Aquí tienes tu primera decisión de camino: el sistema de archivos. Yo uso ext4, que es aburrido y fiable. El camino alternativo es btrfs con snapper, que te da snapshots del sistema antes de cada actualización (muy buen seguro de vida en una rolling release). En su día me quedé con las ganas de probarlo; si te llama, este vídeo de Ermanno lo explica muy bien: How to install Arch Linux with BTRFS & Snapper .

Aviso: en el siguiente bloque no copies y pegues, adapta las particiones a tu disco.

lsblk
# imaginando que vas a usar el disco /dev/sda, aunque podría ser otro
# como /dev/nvme0n1 o /dev/mmcblk0
# sda1 efi  512MB
# sda2 swap entre 2GB y la mitad de la RAM instalada
# sda3 root el espacio restante

# para crear las particiones, lo más sencillo es cfdisk (gpt)
cfdisk
# efi  -> 512MB  type -> EFI System
# swap -> 2048MB type -> Linux swap
# root -> resto  type -> Linux filesystem

# formateo
mkfs.ext4 /dev/_particion_root_
mkswap /dev/_particion_swap_
mkfs.fat -F 32 /dev/_particion_efi_

# montando las particiones
mount /dev/_particion_root_ /mnt
mount --mkdir /dev/_particion_efi_ /mnt/boot
swapon /dev/_particion_swap_

paquetes base

Antes de descargar nada, recomiendo usar reflector para seleccionar los repositorios más rápidos, porque a veces te toca uno que va a pedales:

pacman -Syy
pacman -S reflector
# backup de la lista por si acaso
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak
reflector -c "ES" -f 12 -l 10 -n 12 --save /etc/pacman.d/mirrorlist

Instalamos los paquetes esenciales en la montura. Fíjate en el microcode: intel-ucode si tu CPU es Intel, amd-ucode si es AMD.

pacstrap -K /mnt base linux linux-firmware base-devel nano intel-ucode

Generamos las instrucciones de montaje para que las particiones se monten en cada arranque:

genfstab -U /mnt >> /mnt/etc/fstab

dentro del chroot

Ahora lo que yo llamo la instalación propia de Arch, donde entramos al punto de montaje y empezamos a configurar el sistema:

arch-chroot /mnt

# hora
ln -sf /usr/share/zoneinfo/Europe/Madrid /etc/localtime
hwclock --systohc

# locales: entra en /etc/locale.gen y descomenta en_US.UTF-8
# (y es_ES.UTF-8 si quieres el sistema en español)
nano /etc/locale.gen
locale-gen
echo 'LANG=en_US.UTF-8' > /etc/locale.conf

# keymap de la consola
echo 'KEYMAP=es' > /etc/vconsole.conf

# red
echo 'archpc' > /etc/hostname
cat >> /etc/hosts << 'HOSTS'
127.0.0.1 localhost
::1       localhost
127.0.1.1 archpc
HOSTS

# initramfs
mkinitcpio -P

# contraseña de root
passwd

# usuario (el mío es zft9xgy, pon el tuyo) y sudo
pacman -S sudo
useradd -m zft9xgy
passwd zft9xgy
usermod -aG wheel zft9xgy

# descomentar la linea %wheel ALL=(ALL:ALL) ALL
EDITOR=nano visudo

Por cierto, la versión anterior de esta guía tenía aquí un bug que nadie me reportó en dos años: hacía usermod -aG wheel sobre un usuario que no era el que se había creado dos líneas antes. Si la seguiste al pie de la letra y te quedaste sin sudo, ahora ya sabes por qué.

bootloader

Yo uso GRUB. El camino alternativo minimalista es systemd-boot, que ya viene con systemd y configura en dos líneas; GRUB me compensa por costumbre y porque convive bien con otros sistemas si algún día hay dual boot.

pacman -S grub efibootmgr
mkdir /boot/efi
mount /dev/_particion_efi_ /boot/efi

# algunas placas base no aceptan un bootloader-id con espacios,
# en ese caso usa --bootloader-id=GRUB
grub-install --target=x86_64-efi --bootloader-id="Arch Linux" --efi-directory=/boot/efi

grub-mkconfig -o /boot/grub/grub.cfg

red, bluetooth y audio antes de reiniciar

Muy importante: ahora mismo tienes internet porque estás en el entorno de instalación, pero ese entorno desaparece al reiniciar. Si no dejas instalado y activado lo necesario para conectarte, arrancarás tu Arch nuevo sin red y tocará volver al USB.

pacman -S networkmanager bluez bluez-utils pipewire pipewire-pulse pipewire-alsa wireplumber

systemctl enable NetworkManager
systemctl enable bluetooth

Sobre el audio: hoy la respuesta es PipeWire con WirePlumber, sin discusión. Sustituye a PulseAudio (el paquete pipewire-pulse hace que todo lo que esperaba PulseAudio siga funcionando) y no requiere configurar nada para un uso normal.

Si tu GPU es AMD, como la mía, los drivers son mesa y vulkan-radeon y no hay más historia. Si es NVIDIA, en Hyprland funciona, pero es el camino con más piedras: lee antes la página de NVIDIA de la wiki de Hyprland .

pacman -S mesa vulkan-radeon

Salimos del chroot y reiniciamos:

exit
umount -R /mnt
reboot

fuentes y recursos

primer arranque: yay y paquetes básicos

Inicia sesión con tu usuario y conecta la red (nmtui es lo más cómodo para wifi). Lo primero que instalo es yay, el helper de AUR, porque tarde o temprano vas a querer algún paquete que no está en los repos oficiales:

sudo pacman -S git
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

Y mis básicos de terminal, que aquí sí que cada uno tendrá los suyos:

sudo pacman -S fish micro btop fastfetch unzip wget openssh

Yo uso fish como shell y micro como editor de terminal (sí, existe gente que no usa ni vim ni neovim y vive feliz). btop para monitorizar y lo demás son herramientas que siempre acaban haciendo falta.

Si te interesa el mundillo de la ciberseguridad, existe BlackArch como repositorio adicional con cientos de herramientas de pentesting. Yo no lo tengo instalado: para los CTF y laboratorios prefiero instalar las herramientas concretas que necesito, y así el sistema del día a día se queda limpio.

instalando hyprland

Hyprland es un compositor de Wayland con tiling dinámico. En cristiano: un gestor de ventanas donde estas se organizan solas en mosaico, todo se maneja con teclado, y encima se ve bonito sin pelearte demasiado. Es el motivo por el que mucha gente (yo incluido) acaba en este lado de Linux.

sudo pacman -S hyprland xdg-desktop-portal-hyprland hyprpolkitagent hyprpaper

Además del compositor van ahí tres piezas que no son opcionales aunque lo parezcan: el portal (xdg-desktop-portal-hyprland), que es lo que permite compartir pantalla y que los diálogos de abrir archivo funcionen; el agente polkit (hyprpolkitagent), que es lo que te muestra la ventana de contraseña cuando una app gráfica necesita permisos; y hyprpaper para el fondo de pantalla.

arrancar sesión: mi camino sin display manager

Aquí viene otra decisión: ¿cómo entras a Hyprland al encender el equipo?

Mi elección es la más simple posible: ningún display manager. Inicio sesión en la TTY de texto y escribo Hyprland. Un paquete menos, un servicio menos, una pantalla de login menos que configurar. Para un equipo de una sola persona no necesito más.

Los caminos alternativos, si quieres pantalla de login gráfica: greetd con tuigreet (minimalista, va muy bien con este setup) o SDDM (el clásico, más pesado, más visual).

configurando hyprland en lua

Y llegamos a la parte que más ha cambiado desde que empecé esta guía. Hyprland se configuraba con un archivo hyprland.conf en un formato propio llamado hyprlang. Desde la versión 0.55, hyprlang está deprecado: sigue funcionando por compatibilidad, pero el formato de configuración es ahora Lua, y el .conf tiene fecha de caducidad. Si estás empezando hoy, no tiene sentido aprender un formato que está de salida: empieza directamente en Lua.

La transición está bien resuelta: Hyprland lee ~/.config/hypr/hyprland.lua si existe, y si no, cae al hyprland.conf clásico. Eso te da un mecanismo de respaldo gratis: mientras migras (o mientras aprendes), guarda un .conf funcional en el directorio, y si tu Lua peta un día, renombras el .lua y vuelves al legacy al instante.

El propio paquete trae dos archivos que valen oro:

/usr/share/hypr/hyprland.lua      # config de ejemplo oficial
/usr/share/hypr/stubs/hl.meta.lua # stubs de toda la API (para el LSP)

El primero es el punto de partida para tu config. El segundo, si configuras tu editor con un language server de Lua, te da autocompletado y documentación de toda la API mientras escribes la config, que es algo que hyprlang jamás pudo ofrecer.

No voy a pegar aquí mi configuración entera (está en mis dotfiles ), pero sí la estructura y las ideas que me parecen importantes:

-- ~/.config/hypr/hyprland.lua
---@module 'hl.meta'

-- tus programas, definidos una vez
local terminal = "foot"
local menu     = "rofi -show drun"

-- monitores
hl.monitor({
    output   = "",        -- "" = cualquier salida
    mode     = "highres",
    position = "auto",
    scale    = 1.875,
})

-- teclado
hl.config({
    input = { kb_layout = "es" },
})

-- autostart: hyprland.start sustituye a exec-once y solo
-- dispara al arrancar el compositor, no en cada recarga
hl.on("hyprland.start", function()
    hl.exec_cmd("waybar")
    hl.exec_cmd("hyprpaper")
    hl.exec_cmd("dunst")
end)

-- binds: una cadena legible, un dispatcher, y una descripción
-- que luego aparece en `hyprctl binds` (chuleta gratis)
local mainMod = "SUPER"
hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal), { description = "Terminal" })
hl.bind(mainMod .. " + space",  hl.dsp.exec_cmd(menu),     { description = "Lanzador" })
hl.bind(mainMod .. " + Q",      hl.dsp.window.close(),     { description = "Cerrar ventana" })

-- workspaces: donde antes copiabas 20 lineas casi iguales,
-- ahora escribes un bucle
for i = 1, 10 do
    local key = i % 10
    hl.bind(mainMod .. " + " .. key,         hl.dsp.focus({ workspace = i }))
    hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
end

Ese bucle final resume por qué me gusta el cambio: la config deja de ser texto repetido y pasa a ser un programa pequeñito. Los binds pueden ejecutar funciones Lua (mi ALT+Tab despacha dos acciones seguidas, algo que antes eran dos binds “apilados” sobre la misma tecla), y puedes cargar cosas dinámicamente, como hago yo con los colores de pywal.

Dos consejos aprendidos por las malas:

Programa a la defensiva. Un error de Lua al cargar la config tira a Hyprland a “modo emergencia” y te quedas sin ningún keybind. Todo lo que cargues de fuera (archivos generados por otras herramientas, APIs que puedan cambiar) envuélvelo en pcall y ten un fallback. Mi config carga los colores de pywal así: si el archivo no existe o está a medio escribir, caen unos colores fijos y la sesión arranca igual.

Verifica qué config está leyendo de verdad. Si migras desde un .conf, recuerda que la sesión en marcha sigue con la config con la que arrancó. Yo me tiré un día entero convencido de que mi Lua estaba activo cuando Hyprland seguía corriendo con el .conf viejo. La comprobación es una línea:

hyprctl systeminfo | grep configProvider
# configProvider: lua  <- lo que quieres ver

el escritorio pieza a pieza

Hyprland solo gestiona ventanas. Todo lo demás que asocias a “un escritorio” son piezas que eliges tú. Esta es la parte donde no debes copiarme: para cada necesidad te digo qué uso yo y qué alternativas sensatas hay, y tú decides.

Barra de estado: waybar . Aquí hay poco camino que elegir: no existe barra nativa de Hyprland (ojo, el plugin hyprbars son barras de título por ventana, no una barra de estado) y waybar es el estándar de facto. Se configura con un JSON y CSS, y puedes hacerla tan sobria o tan recargada como quieras.

Lanzador de aplicaciones: rofi . Desde la versión 2.0 tiene soporte nativo de Wayland. Lo uso para lanzar apps, como calculadora, para buscar archivos y como menú del historial del portapapeles: cuatro necesidades, una herramienta. Alternativas: wofi (más simple, yo vengo de ahí), fuzzel (minimalista). Probé hyprlauncher, la opción nativa, y la descarté: no busca archivos y su modo dmenu no me servía para el portapapeles.

Notificaciones: dunst . Ligero, se configura con un archivo de texto y no da guerra. No hay equivalente nativo de Hyprland. Alternativas: mako, o swaync si quieres un centro de notificaciones completo.

Fondo de pantalla: hyprpaper + pywal . hyprpaper es la opción nativa y hace una cosa y la hace bien. pywal es el truco de magia: extrae una paleta de colores del fondo de pantalla y la genera para el resto de apps (mi terminal, waybar y los bordes de ventana de Hyprland comparten paleta con el wallpaper). Alternativa: swww si quieres transiciones animadas entre fondos.

Bloqueo e inactividad: swaylock-effects + swayidle. El combo veterano: swayidle vigila la inactividad y dispara el bloqueo, swaylock pinta la pantalla de bloqueo. El camino nativo actual es hyprlock + hypridle, y es probablemente lo que te recomendaría si empiezas de cero; yo aún no he migrado porque lo que tengo funciona y esa migración la estoy haciendo por fases.

Capturas de pantalla: hyprshot + hyprpicker. Aquí sí he migrado ya a las nativas: hyprshot para capturar región, ventana o pantalla, y hyprpicker como cuentagotas que copia el color en hex. Por debajo siguen grim + slurp, que conviene dejar instalados porque otros programas los usan.

Portapapeles con historial: cliphist + wl-clipboard. Un daemon guarda todo lo que copias y un bind lo saca en rofi para recuperar cualquier cosa. De las piezas que cuando las pruebas ya no sabes vivir sin ellas.

Luz nocturna: gammastep. Filtro de luz azul según la hora. El camino nativo es hyprsunset; está en mi lista de migraciones pendientes.

Audio: pipewire + wireplumber. Ya lo instalamos antes de reiniciar. Para el día a día: pactl en los binds de volumen, playerctl para controlar la música desde el teclado y pavucontrol cuando necesito una mesa de mezclas gráfica.

Gestor de archivos: thunar. Gráfico, ligero, sin más pretensiones. En terminal, yazi o ranger son caminos muy dignos si vives en la consola.

Apariencia GTK: nwg-look. Las apps GTK no heredan el tema por arte de magia en Wayland; nwg-look te deja elegir tema, iconos y cursor sin pelearte con archivos de configuración.

sudo pacman -S waybar rofi dunst hyprpaper python-pywal swaylock-effects swayidle \
  hyprshot hyprpicker cliphist wl-clipboard gammastep pavucontrol playerctl \
  thunar nwg-look

detalles de mi setup que quizá te ahorren horas

Estas son cosas concretas de mi configuración que no salen en las guías genéricas y que me costaron lo suyo:

Escala fraccionaria y apps GTK. Mi monitor va a escala 1.875, y con escalas fraccionarias las apps GTK pueden descuadrarse (en mi caso, waybar dejaba de responder a los clics porque gtk-layer-shell desalineaba las coordenadas). La solución fue lanzar waybar con env GDK_SCALE=1 GDK_DPI_SCALE=1.875, forzando a GTK a no escalar y compensando el tamaño visual. Si usas escala entera (1x, 2x), olvídate de este párrafo.

Brillo de monitores externos desde el teclado. Los portátiles traen brightnessctl y a correr, pero en un sobremesa el brillo del monitor se cambia por DDC/CI con ddcutil . Mis teclas de brillo llaman a un script que escribe valores absolutos en vez de relativos, porque mi monitor no devuelve lecturas DDC fiables y la forma relativa (que necesita leer antes de escribir) fallaba de forma aleatoria. Si tus binds de brillo “a veces funcionan”, puede que te esté pasando esto.

Los dotfiles, en un repo. Toda esta configuración vive en github.com/zft9xgy/dotfiles y se sincroniza entre mis máquinas. El día que esta guía me haga falta de verdad, el grueso del trabajo será un git clone.

¿y el homelab?

La versión anterior de esta guía prometía una sección de “instalando homelab” que nunca llegó, y ya no va a llegar: el homelab se merece sus propios posts. Si te interesa ese camino, empieza por el inicio del proyecto y sigue con Pi-hole en Docker con red macvlan .

fuentes y recursos

Y esto es todo. Dos años después, la guía por fin se ha quitado el “[incompleto]” del título. Si te montas tu escritorio con ella y eliges caminos distintos a los míos, me encantaría saber cuáles: mis datos de contacto están abajo.