Blog
/how-to-install-arch-linux-manually

How to Install Arch Linux Manually

35 min read

There are two kinds of people in this world: those who click "Next" through an installer, and those who build their operating system brick by brick with their own hands. Arch Linux is for the second kind.

Installing Arch manually isn't just about getting an OS running - it's about understanding every single piece that makes your system boot. By the end of this guide you'll know what an EFI partition does, why fstab exists, and where your bootloader lives. And yes, you'll also earn eternal bragging rights: "I use Arch btw."

This guide is written to be the only resource you need - based on the official ArchWiki (as of July 2026), assuming a standard UEFI laptop, covering everything from downloading the ISO to your first successful login.

πŸ’‘ Honest disclosure: The same ISO ships an official guided installer, archinstall, that handles partitioning, bootloader, and desktop setup interactively if you want a working system fast. This guide is for people who want to understand every step - which is exactly why manual installation is worth doing at least once.

⚑ Already done this before? Skip to the fast path

Jump straight to the Complete Command Cheat Sheet. Every detailed section below exists for first-timers - each command is explained once, then used without ceremony.

⚠️ Before we start: This process will erase the target disk completely. Back up anything important first. Read each step fully before running any command. Your data cannot be recovered once formatted.


1. What You'll Need

RequirementDetails
πŸ’» Laptop/DesktopAny x86_64 machine with UEFI firmware (anything from ~2014 onwards)
πŸ”Œ PowerLaptop plugged into AC power - do NOT attempt this on battery alone
🌐 InternetWi-Fi or Ethernet (needed during installation)
πŸ’Ύ USB driveMinimum 2 GB, everything on it will be erased
⏱️ Time45-90 minutes for your first attempt
🧠 PatienceReading skills > copy-paste skills

2. Download and Verify the ISO

Download

Get the latest ISO from the official download page: archlinux.org/download

Pick a mirror close to your location for faster speeds. For example, if you're in India:

BASH SnippetBASH
wget https://mirrors.nxtgen.com/archlinux/iso/latest/archlinux-x86_64.iso

(Mirror URLs rotate over time - if that link 404s, grab a fresh one from the download page. The latest path always points at the newest release.)

Corrupted downloads cause mysterious failures hours later. Verify first:

BASH SnippetBASH
sha256sum archlinux-x86_64.iso

Compare the output hash against the SHA256 value on the download page (the sha256sums.txt file). They must match exactly.

For stronger guarantees, verify the PGP signature instead - the .sig file is a cryptographic signature, not a checksum file (you don't compare hashes against it):

BASH SnippetBASH
pacman-key -v archlinux-x86_64.iso.sig

A checksum proves the download isn't corrupted; a valid signature proves it genuinely came from Arch. The ArchWiki recommends the signature route when you can use it.


3. Create the Bootable USB

On Linux - using dd

First identify your USB drive (very carefully):

BASH SnippetBASH
lsblk

You'll see something like:

TEXT SnippetTEXT
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    1  14.9G  0 disk             <-- your USB drive
└─sda1        8:1    1  14.9G  0 part
nvme0n1     259:0    0 476.9G  0 disk             <-- your internal SSD (DO NOT TOUCH)
β”œβ”€nvme0n1p1 259:1    0   512M  0 part /boot/efi
└─nvme0n1p2 259:2    0 476.4G  0 part /

Look at the SIZE column and the RM column (RM 1 means Removable Media - usually the USB). Now flash it:

BASH SnippetBASH
dd bs=4M if=archlinux-x86_64.iso of=/dev/sdX status=progress oflag=sync

Replace /dev/sdX with your actual USB device (e.g., /dev/sdb). Not sdX1 - the whole device, not a partition. This takes 2-5 minutes. When it finishes, sync and eject:

⚠️ Common mistake: Picked sdX1 (a partition) instead of sdX (the whole drive)? You'd write the ISO onto a partition and the USB wouldn't boot - or worse, onto the wrong disk and wipe your data. If you ever do target the wrong device, stop immediately; see Troubleshooting - data may still be recoverable if you write nothing else.

BASH SnippetBASH
sync

On Windows - using Rufus

  1. Download Rufus
  2. Device β†’ your USB drive
  3. Boot selection β†’ SELECT β†’ pick the Arch ISO
  4. Partition scheme β†’ GPT, Target system β†’ UEFI (non CSM)
  5. Click START β†’ when asked, choose Write in DD Image mode (recommended over ISO mode)

Alternative - Ventoy (works everywhere)

Install Ventoy on your USB once, then simply drag-and-drop ISO files onto it. At boot, Ventoy gives you a menu to pick any ISO on the stick. Great if you keep multiple distros around.


4. Boot From the USB

  1. Shut down the laptop completely (disable Fast Startup on Windows first if dual-booting).
  2. Plug in the USB drive.
  3. Power on and hammer the boot menu key for your brand:
BrandBoot Menu KeyBIOS/UEFI Setup Key
DellF12F2
HPEsc or F9Esc or F10
LenovoF12 (some: Fn+F12)F1 or F2
ASUSEscF2 or Del
AcerF12F2
MSIF11Del
ToshibaF12F2
SamsungEsc or F10F2
Xiaomi/MiF12F2
  1. In the boot menu, look for two entries for your USB - pick the one containing "UEFI":
TEXT SnippetTEXT
UEFI: SanDisk Cruzer Blade 1.26    <-- βœ… choose this one
SanDisk Cruzer Blade 1.26          <-- ❌ legacy/CSM entry, skip it
  1. When the Arch menu appears, select "Arch Linux install medium (x86_64, UEFI)" and press Enter.

Disable Secure Boot (if the USB won't boot)

If your machine refuses to boot the USB, Secure Boot may be blocking it. Reboot into BIOS/UEFI Setup (key from table above), find Security or Boot tab β†’ set Secure Boot β†’ Disabled β†’ save (F10) and retry.


5. Pre-Installation Setup

After loading, you're dropped into a Zsh shell running as root, with internet tools ready. Work through these checks in order.

5.1 Verify You Are in UEFI Mode

This is mandatory - the entire guide assumes UEFI:

BASH SnippetBASH
ls /sys/firmware/efi/efivars
  • βœ… Files/directories listed β†’ you're in UEFI mode. Continue.
  • ❌ "No such file or directory" β†’ you booted in Legacy/CSM mode. Reboot, go into UEFI setup, disable CSM/Legacy Boot, and re-enter the installer via the UEFI USB entry.

5.2 Connect to the Internet

Wi-Fi - full iwctl walkthrough

iwctl is the interactive client for iwd. Run it:

BASH SnippetBASH
iwctl

Your prompt changes to [iwd]#. Now, step by step:

TEXT SnippetTEXT
[iwd]# device list

Confirms your wireless adapter exists (usually wlan0) and shows whether it's powered on. If it shows "off":

TEXT SnippetTEXT
[iwd]# device wlan0 set-property Powered on

Scan for networks:

TEXT SnippetTEXT
[iwd]# station wlan0 scan
[iwd]# station wlan0 get-networks

You'll see a list of SSIDs with signal strength. Connect to yours:

TEXT SnippetTEXT
[iwd]# station wlan0 connect "YourWiFiName"

Type the passphrase when prompted (it's also invisible). Then leave:

TEXT SnippetTEXT
[iwd]# exit

If the adapter seems blocked entirely, unblock it from the normal shell:

BASH SnippetBASH
rfkill unblock all

Ethernet

Just plug the cable in. That's it - DHCP handles the rest.

Verify the Connection (do not skip)

BASH SnippetBASH
ping -c 3 archlinux.org

If you get replies, continue. If not, fix connectivity now - nothing later works without internet.

5.3 Update the System Clock

Live environments often boot with the wrong time, and a wrong clock breaks HTTPS downloads:

BASH SnippetBASH
timedatectl set-ntp true
timedatectl

Check the output says System clock synchronized: yes.

5.4 (Optional) Comfort Tweaks

Bigger console font for high-resolution screens:

BASH SnippetBASH
setfont ter-132b

Non-US keyboard layout:

BASH SnippetBASH
loadkeys de      # German example; see `localectl list-keymaps`

6. Understand the Partition Plan

Before touching any disk, understand what we're creating and why. We're making a clean GPT layout with three core partitions - plus one optional fourth if you want your personal files on their own slice of disk:

#PartitionExample DeviceSizeFilesystemPurpose
1EFI System Partition (ESP)/dev/nvme0n1p1512 MB (up to 1 GB)FAT32Holds the bootloader (GRUB) and boot files. UEFI firmware reads this to start your OS
2Swap/dev/nvme0n1p2See belowLinux swapOverflow RAM + enables hibernation
3Root/dev/nvme0n1p360 GB (see below)ext4Your entire OS - kernel, apps, system files
4Home (optional)/dev/nvme0n1p4Rest of diskext4Your personal files - /home/you lives here

One More Choice: Separate /home? (Optional - or skip it)

You can fully skip a separate /home partition and let everything - system and your files - live together on the single root partition. That's simpler and perfectly fine for most people. Or you can split one off. Here's the honest trade-off so you can decide:

🟒 Single root partition (skip /home)🟑 Separate /home partition (create one)
ProsSimplest setup; no guessing sizes; every byte available to both OS and filesYour files survive a reinstall/format of root; you can hop distros without losing data; root stays small & predictable; easier to back up or snapshot independently
ConsIf you reinstall, your personal files go with the root format; one big filesystem means one big failure domainYou must pick a size split up front; if /home is too small your files overflow while root still has free space (and vice-versa) - repartitioning later is annoying
Best forFirst-timers, small disks, "set and forget" installsPeople who reinstall often, dual/triple-boot, or want clean separation of system vs data

The split we'll use if you choose to create one: give root a comfortable 60 GB (/dev/nvme0n1p3), then let /home (/dev/nvme0n1p4) take everything else. 60 GB is plenty for the OS plus a desktop environment and a healthy app library; your music, photos, games, and downloads then breathe in the spacious /home partition. If you'd rather skip it, just leave root as the "rest of disk" partition exactly as the base walkthrough below does, and ignore every /home note.

πŸ’‘ Can't decide? Skip it. You can always move /home to a new partition later once you've seen how much space your files actually eat - but doing it during install is by far the least painful moment.

Swap Size Cheat Sheet

Installed RAMSwap (no hibernation)Swap (with hibernation)
≀ 4 GB2Γ— RAM3Γ— RAM
8 GB4 GB8 GB (equal to RAM)
16 GB+4-8 GB is plentyEqual to RAM

The "with hibernation" column is deliberately conservative. The kernel compresses the hibernation image (by default targeting roughly 2/5 of your RAM), so swap somewhat smaller than RAM often still hibernates fine - equal-to-RAM is simply the safe target that never fails.

πŸ’‘ Modern alternative: Many setups now skip disk swap entirely and use zram - a compressed swap device living in RAM. It's faster, saves disk space, and shines on machines with 16 GB+ RAM. This guide uses a real partition because it's simpler and enables hibernation on laptops. See the ArchWiki zram page if you're curious.

Want Hibernation Later? Read This Now

Creating swap does not enable hibernation by itself - it only provides the storage the sleep image is written to. The good news: sizing swap now puts you 90% of the way there. The remaining step (telling the kernel where to resume from) is covered in Step 13, and needs nothing more than one kernel parameter. Details live in the ArchWiki Power management page.

Know Your Device Names

Device names differ by bus type - know which one is yours before continuing:

Disk TypeDevice NamePartitions Look Like
NVMe SSD (M.2)/dev/nvme0n1/dev/nvme0n1p1, /dev/nvme0n1p2...
SATA SSD/HDD/dev/sda/dev/sda1, /dev/sda2...

⚠️ Triple-check the disk name. Formatting the wrong device destroys that drive's data instantly. There is no undo.


7. Partitioning - Full Walkthroughs (cfdisk & fdisk)

Both tools do the same job. Pick one:

  • cfdisk β†’ menu-driven, arrow keys, harder to mess up. Recommended for first-timers.
  • fdisk β†’ pure keyboard commands, faster, feels like a proper hacker. Same result.

Quick chooser before diving in:

TEXT SnippetTEXT
Partitioning tool?
β”œβ”€ First time / want arrows & menus β†’ cfdisk (Method 1)
└─ Comfortable with raw CLI         β†’ fdisk   (Method 2)

Swap size?
β”œβ”€ No hibernation planned β†’ 4 GB is plenty
└─ Want hibernation       β†’ match your RAM (table above)

Separate /home partition?
β”œβ”€ Skip it (everything on root)      β†’ root = rest of disk, ignore /home steps
└─ Create one (files survive reinstall) β†’ root = 60 GB, /home = rest (steps below)

ESP mount point?
└─ This guide mounts it at /boot - simplest setup with GRUB

Identify your target disk one final time:

BASH SnippetBASH
lsblk

In the examples below I'll use /dev/nvme0n1 (NVMe). If yours is SATA, substitute /dev/sda and remember partitions become sda1, sda2, sda3.


7a. Method 1: cfdisk (Beginner-Friendly)

Launch it:

BASH SnippetBASH
cfdisk /dev/nvme0n1

Now follow along exactly:

Step 1 - Select label type. If asked to "Select label type", choose gpt and press Enter. (If it opens straight into a visual view of existing partitions, that's fine too.)

Step 2 - Create the EFI partition.

  1. Arrow down to Free space.
  2. Arrow right to New β†’ press Enter.
  3. Partition size: type 512M β†’ Enter.
  4. The new partition is highlighted. Arrow right to Type β†’ Enter.
  5. Select EFI System β†’ Enter.

Step 3 - Create the swap partition.

  1. Arrow down to Free space again.
  2. New β†’ size: type 4G β†’ Enter.
  3. Arrow right to Type β†’ Enter.
  4. Select Linux swap β†’ Enter.

Step 4 - Create the root partition.

  1. Arrow down to the last Free space.
  2. New β†’ size: accept the default (it already shows the remaining space) β†’ Enter. (If you're making a separate /home partition, type 60G here instead so there's free space left for it.)
  3. Leave its type as the default Linux filesystem (newer versions may call it Linux x86-64 root (/) - either works).

Step 4b - (Optional) Create the /home partition. Skip this entirely if you decided to keep everything on the single root partition.

  1. Arrow down to the Free space that remains.
  2. New β†’ size: accept the default (remaining space) β†’ Enter.
  3. Leave its type as the default Linux filesystem.

Step 5 - Write changes.

  1. Arrow right to Write β†’ Enter.
  2. It asks for confirmation: type yes β†’ Enter. Nothing touches the disk until this moment.
  3. Arrow right to Quit β†’ Enter.

Step 6 - Verify:

BASH SnippetBASH
lsblk

You should see three partitions under your disk (512M, 4G, rest) - or four if you made /home. If something looks wrong, just run cfdisk again and delete/recreate partitions - nothing was formatted yet, so this is still safe.


7b. Method 2: fdisk (Keyboard Warrior)

Launch it:

BASH SnippetBASH
fdisk /dev/nvme0n1

You're greeted by Command (m for help):. Type each letter shown below and press Enter after each. Prompts are shown in italics-style comments.

Step 1 - Create a fresh GPT partition table:

TEXT SnippetTEXT
Command (m for help): g
Created a new GPT disklabel (GUID: ...).

This wipes the old partition table structure (data still untouched until write).

Step 2 - Create partition 1 (EFI):

TEXT SnippetTEXT
Command (m for help): n
Partition number (1-128, default 1): 1
First sector (2048-..., default 2048): ⏎        ← just press Enter
Last sector, Β±sectors ...: +512M                 ← type +512M then Enter

Created a new partition 1 of type 'Linux filesystem' and of size 512 MiB.

Step 3 - Set partition 1 type to EFI System:

TEXT SnippetTEXT
Command (m for help): t
Selected partition 1 (default)
Partition type or alias (type L to list all): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.

(If 1 isn't accepted, type L to list all type codes and use the number shown next to "EFI System".)

Step 4 - Create partition 2 (swap):

TEXT SnippetTEXT
Command (m for help): n
Partition number (... default 2): 2
First sector: ⏎                                  ← press Enter
Last sector, ...: +4G                            ← type +4G then Enter

Step 5 - Set partition 2 type to Linux swap:

TEXT SnippetTEXT
Command (m for help): t
Partition number (1-3, default 3): 2
Partition type or alias (type L to list all): 19
Changed type of partition 'Linux filesystem' to 'Linux swap'.

(Again, if 19 doesn't map to "Linux swap" on your version, check the list with L.)

Step 6 - Create partition 3 (root):

TEXT SnippetTEXT
Command (m for help): n
Partition number (... default 3): 3
First sector: ⏎                                  ← press Enter
Last sector, ...: ⏎                              ← press Enter, accepts ALL remaining space

(If you're creating a separate /home partition, type +60G here instead so free space remains for it.)

Leave partition 3's type as the default Linux filesystem.

Step 6b - (Optional) Create partition 4 (/home). Skip this if you decided to keep everything on the single root partition.

TEXT SnippetTEXT
Command (m for help): n
Partition number (... default 4): 4
First sector: ⏎                                  ← press Enter
Last sector, ...: ⏎                              ← press Enter, accepts ALL remaining space

Leave partition 4's type as the default Linux filesystem - no t needed.

Step 7 - Review everything before writing:

TEXT SnippetTEXT
Command (m for help): p

Carefully read the printout. You want:

TEXT SnippetTEXT
Device         Start       End   Sectors   Size Type
/dev/nvme0n1p1  2048   1050623   1048576   512M EFI System
/dev/nvme0n1p2      ...                    4G  Linux swap
/dev/nvme0n1p3      ...                   60G  Linux filesystem   (or "rest" if you skipped /home)
/dev/nvme0n1p4      ...                  rest Linux filesystem   (only if you made /home)

Step 8 - Write and exit:

TEXT SnippetTEXT
Command (m for help): w
The partition table has been altered.
Syncing disks.

Like cfdisk, nothing is committed until w. Made a mistake earlier? Press q instead to quit discarding all changes, and start over.

Verify:

BASH SnippetBASH
lsblk

Three partitions present (or four with /home)? Perfect. Either way you got here - proceed.


8. Format the Partitions

Partitions exist but have no filesystem yet. Format each with its correct type:

BASH SnippetBASH
mkfs.fat -F32 /dev/nvme0n1p1       # EFI partition β†’ FAT32
mkswap /dev/nvme0n1p2              # Swap partition β†’ swap signature
mkfs.ext4 /dev/nvme0n1p3           # Root partition β†’ ext4 journaling FS
mkfs.ext4 /dev/nvme0n1p4           # Home partition β†’ ext4 (ONLY if you created one)

Notes:

  • -F32 forces FAT32 even on larger ESPs - UEFI requires FAT.
  • mkfs.ext4 prints a filesystem UUID at the end. Noted? Doesn't matter - we use UUIDs automatically later anyway.
  • These commands erase data permanently. Double-check the device numbers match your layout from lsblk.

Why these choices?

FilesystemUsed ForWhy
FAT32EFI partitionThe only filesystem UEFI firmware is guaranteed to read
swapSwap partitionKernel swaps memory pages to/from it directly
ext4RootBattle-tested, fast, journaling, zero-surprises default

9. Mount Everything

Now assemble the future filesystem tree under /mnt. Order matters: parent first, children after.

BASH SnippetBASH
swapon /dev/nvme0n1p2              # activate swap
mount /dev/nvme0n1p3 /mnt          # mount root FIRST
mkdir -p /mnt/boot                 # create the boot directory inside root
mount /dev/nvme0n1p1 /mnt/boot     # mount EFI partition INTO /mnt/boot
mkdir -p /mnt/home                 # create the home directory inside root
mount /dev/nvme0n1p4 /mnt/home     # mount Home partition (ONLY if you created one)

⚠️ Order matters - the /home mount (last line) must happen before Step 11's genfstab runs, otherwise it won't appear in fstab and your files would land on the root partition instead. If you skipped /home, just omit those last two lines.

What just happened conceptually: inside the installed system, /boot will be that FAT32 partition. GRUB gets installed there, and UEFI finds it there.

Verify the whole stack:

BASH SnippetBASH
lsblk

Expected:

TEXT SnippetTEXT
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
nvme0n1     259:0    0 476.9G  0 disk
β”œβ”€nvme0n1p1 259:1    0   512M  0 part /mnt/boot     βœ…
β”œβ”€nvme0n1p2 259:2    0     4G  0 part [SWAP]        βœ…
β”œβ”€nvme0n1p3 259:3    0    60G  0 part /mnt          βœ…
└─nvme0n1p4 259:4    0 412.4G  0 part /mnt/home     βœ…   (only if you made /home)

All mounted correctly - including p4 β†’ /mnt/home if you made one? Beautiful.


10. Install the Base System (pacstrap)

(Optional but Smart) Set Up Your Mirror List First

Downloads pull from mirrors in the order they appear in /etc/pacman.d/mirrorlist. A server on another continent means slow, laggy downloads for every package you install today - so spend two minutes fixing this.

This is better any day: country-local mirrors give you the lowest latency, and you hand-pick exactly which servers you trust instead of letting a script gamble on whatever pinged fastest.

  1. Open archlinux.org/mirrorlist in a browser.

  2. Select your country, optionally tick IPv4 / IPv6 / HTTPS only, then submit the form.

  3. Copy the generated output.

  4. On the live ISO, open the mirror file:

    BASH SnippetBASH
    nano /etc/pacman.d/mirrorlist
    
  5. Delete the existing contents and paste your generated list.

  6. Uncomment the servers - the generator outputs every line commented out. Remove the ## prefix so each entry becomes active:

    TEXT SnippetTEXT
    ## Server = https://mirrors.nxtgen.com/archlinux/extra/os/x86_64    ❌ inactive
    Server = https://mirrors.nxtgen.com/archlinux/extra/os/x86_64       βœ… pacman will use this
    

    Uncomment at least your first 2-3 preferred servers (having spares costs nothing).

  7. Save (Ctrl+S) and exit (Ctrl+X). Done - pacman now downloads from your country's mirrors first.

Option B - Automatic Speed Sort with reflector

Can't be bothered? One command sorts all mirrors worldwide by measured speed:

BASH SnippetBASH
reflector --latest 20 --sort rate --save /etc/pacman.d/mirrorlist

reflector ships pre-installed on the live ISO. It works well, but it ranks purely by ping - an unreliable mirror that responds quickly can end up at the top. That's why Option A is the safer bet.

⚠️ Two caveats on reflector: recent ISOs no longer auto-run reflector.service at boot (rating every mirror took too long), so your mirrorlist stays default unless you run it yourself. The project has also been through unmaintained spells upstream, with its future on the ISO under discussion. Option A isn't just safer - it's future-proof.

The Main Event

BASH SnippetBASH
pacstrap -K /mnt base linux linux-firmware vim nano networkmanager intel-ucode amd-ucode base-devel man-db man-pages texinfo

This downloads and installs packages directly into /mnt. What each package is for:

PackageWhy It's Here
baseMinimal toolset: bash, pacman, coreutils, systemd
linuxThe kernel itself - the heart of the OS
linux-firmwareFirmware blobs for Wi-Fi, GPUs, Bluetooth, etc. Without it, hardware stays dead
vim / nanoText editors for config files (keep both, or trim to your favorite)
networkmanagerManages Wi-Fi/Ethernet - powers nmcli, nmtui, and desktop applets later
intel-ucodeCPU bugfix microcode for Intel CPUs
amd-ucodeCPU microcode for AMD CPUs
base-develCompiler toolchain, make, sudo and friends. Not needed to boot - but required later for building AUR helpers like yay
man-db / man-pages / texinfoManual pages. Without these, man pacman finds nothing (base doesn't include them)

Installing both ucode packages is harmless - only the matching one gets used at boot.

πŸ“¦ Firmware note: linux-firmware is a meta-package pulling in the common set of firmware sub-packages (Intel/Realtek/Atheros Wi-Fi, AMD/NVIDIA GPU blobs...). Some hardware wants extras: sof-firmware for the audio DSP on many newer Intel laptops, for example. If something's dead after first boot, check the ArchWiki Linux firmware page for your hardware.

The -K flag initializes pacman's keyring freshly inside the target - prevents signature errors.

Grab a coffee β˜• - this step downloads several hundred MB.


11. Generate fstab

fstab is the file that tells Linux which partitions to mount at boot. Generate it from the current mounts:

BASH SnippetBASH
genfstab -U /mnt >> /mnt/etc/fstab
  • -U β†’ use UUIDs instead of device names (names can change between boots; UUIDs never do).
  • >> β†’ append into the new system's fstab.

VERIFY IT (the step everyone skips, then regrets)

BASH SnippetBASH
cat /mnt/etc/fstab

You must see three active lines (four if you made a /home partition) (UUIDs will differ):

TEXT SnippetTEXT
UUID=xxxx-xxxx  /boot      vfat    rw,...  0 2
UUID=xxxxxxxxx  none       swap    defaults  0 0
UUID=xxxxxxxxx  /          ext4    rw,relatime  0 1
UUID=xxxxxxxxx  /home      ext4    rw,relatime  0 2   # ONLY if you made a /home partition

One line per partition: ESP β†’ /boot, swap, root β†’ /, and /home if you created it. Missing one? Something wasn't mounted during genfstab - go back to Step 9, remount properly, and regenerate (empty the file first with > /mnt/etc/fstab then rerun genfstab). If a bad line later drops you to an emergency shell, see Troubleshooting.


12. Configure Inside Chroot

Chroot = change root. Your shell now operates inside the installed system instead of the live environment:

BASH SnippetBASH
arch-chroot /mnt

Notice your prompt changes - if it still says root@archiso, you're not inside; run the command again and check /mnt is mounted (Step 9). From here until Step 14, every command affects the new install.

12.1 Time Zone

Find your zone:

BASH SnippetBASH
ls /usr/share/zoneinfo/
ls /usr/share/zoneinfo/Asia/

Link it and sync the hardware clock:

BASH SnippetBASH
ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc

(Examples: Asia/Kolkata, Europe/London, America/New_York, Australia/Sydney - whatever matches you.)

12.2 Locale (System Language)

Edit the locales file:

BASH SnippetBASH
nano /etc/locale.gen

Scroll and uncomment (remove the leading #) your locale, e.g.:

TEXT SnippetTEXT
en_US.UTF-8 UTF-8

Save (Ctrl+S) and exit (Ctrl+X). Generate it:

BASH SnippetBASH
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf

12.3 Console Font & Keymap (Optional)

If you changed the keyboard layout in the live env (Step 5.4), make it permanent:

BASH SnippetBASH
echo "KEYMAP=us" > /etc/vconsole.conf      # your layout
echo "FONT=ter-132b" >> /etc/vconsole.conf # optional big font

12.4 Hostname

Your computer's network name. Rules: lowercase letters, digits, hyphens only; no spaces; max 63 chars:

BASH SnippetBASH
echo "myarchlaptop" > /etc/hostname

Map it in hosts:

BASH SnippetBASH
nano /etc/hosts

Make it contain exactly:

TEXT SnippetTEXT
127.0.0.1   localhost
::1         localhost
127.0.1.1   myarchlaptop.localdomain myarchlaptop

Line-by-line: IPv4 loopback, IPv6 loopback, then your machine's own name resolution (replace myarchlaptop with your hostname from above, in both places). The 127.0.1.1 line is technically optional - it's a Debian convention that helps machines without a permanent IP resolve their own hostname - but it's harmless and saves head-scratching later. Keep it.

12.5 Initramfs (Just Verify)

pacstrap already generated the initramfs (the mini-system that loads real drivers at boot). Confirm it exists:

BASH SnippetBASH
ls /boot/

You should see initramfs-linux.img and vmlinuz-linux among the files.

Worth understanding while you're here - the recipe that builds that image lives in the HOOKS array of /etc/mkinitcpio.conf, and the defaults changed with mkinitcpio v40 (late 2025). Fresh installs now use systemd-based hooks instead of the old busybox ones:

HookWhat it does for you
systemdReplaces busybox udev inside the initramfs. Actively developed - and what lets UEFI systems auto-detect the hibernate-resume partition
microcodePacks your CPU's microcode updates inside initramfs-linux.img itself - no separate boot entry needed anymore
kmsLoads GPU drivers early, so your console gets native resolution during boot instead of flickering to it halfway

Two visible side effects on new installs: you'll find no separate intel-ucode.img/amd-ucode.img in /boot (it's bundled now), and no fallback image (mkinitcpio stopped generating those by default). If you ever add Btrfs or LUKS encryption later, this config file is where extra hooks go - today, leave it alone.

12.6 Set Root Password

BASH SnippetBASH
passwd

Type the password twice. Nothing appears while typing - no dots, no asterisks. That's normal. This is the emergency/admin account.

12.7 Create Your Daily User

Never browse as root. Create a real user:

BASH SnippetBASH
useradd -m -G wheel -s /bin/bash yourusername
passwd yourusername

Flag decoder:

FlagMeaning
-mCreate a home directory (/home/yourusername)
-G wheelAdd to the wheel group - the traditional "can use sudo" group
-s /bin/bashSet Bash as login shell

Because /mnt/home was mounted (Step 9) before this chroot, that -m home directory is created directly on your /home partition - no extra steps needed. Skip /home and it simply lands on root instead.

12.8 Enable Sudo for the Wheel Group

Install sudo's policy editor - sudo itself already came with base-devel in Step 10:

BASH SnippetBASH
EDITOR=nano visudo

Why visudo and not editing directly? It validates syntax before saving - a typo in sudoers could lock every admin account out of the machine forever.

Inside the editor, find this line:

TEXT SnippetTEXT
#%wheel ALL=(ALL:ALL) ALL

Delete the # (and the single space after it) so it reads exactly:

TEXT SnippetTEXT
%wheel ALL=(ALL:ALL) ALL

Meaning: members of group wheel may run any command as anyone. Save and exit. Quick test later after reboot: sudo whoami should answer root.


13. Install the GRUB Bootloader

Without a bootloader, the machine boots to nothing. GRUB bridges UEFI β†’ kernel, handles dual-booting, and is the most flexible choice - which is why this guide uses it.

πŸ’‘ GRUB isn't the only option. For a UEFI-only single-OS machine, systemd-boot is a lighter, simpler bootloader with fewer moving parts - and it's what the ArchWiki tends to prefer for UEFI setups. This guide sticks with GRUB for its flexibility, but if you want the minimal route, see the ArchWiki systemd-boot page.

BASH SnippetBASH
pacman -S grub efibootmgr
  • grub β†’ the bootloader itself
  • efibootmgr β†’ manages UEFI boot entries (lets grub-install register itself in firmware)

Install GRUB to the ESP:

BASH SnippetBASH
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB

Flag meanings:

FlagMeaning
--target=x86_64-efiBuild/install for UEFI (not legacy BIOS)
--efi-directory=/bootWhere the ESP is mounted (we mounted it at /boot in Step 9)
--bootloader-id=GRUBName shown in your firmware's boot menu

Success looks like: Installing for x86_64-efi platform. Installation finished. No error reported.

Optional: Wire Up Hibernation (do this before generating config)

If you sized swap for hibernation back in Step 6, this is the moment to finish the job - one kernel parameter tells the kernel which partition to resume from:

BASH SnippetBASH
blkid /dev/nvme0n1p2        # copy the UUID=... value of your SWAP partition
nano /etc/default/grub

Find the line starting with GRUB_CMDLINE_LINUX_DEFAULT and add the parameter inside the quotes:

TEXT SnippetTEXT
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 resume=UUID=xxxx-xxxx-xxxx-xxxx"

Save and exit. The grub-mkconfig in the next step picks it up automatically. (Modern installs get partial help for free - the systemd-based initramfs from Step 12.5 can detect the resume partition via an EFI variable - but an explicit resume= is the dependable belt-and-braces method.)

Skip this if you don't plan to hibernate.

Generate the actual configuration:

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

Watch the output - healthy signs include:

TEXT SnippetTEXT
Found linux image: /boot/vmlinuz-linux
Found initrd image: /boot/initramfs-linux.img

What about microcode? Depends on your mkinitcpio version. Newer installs bundle it inside initramfs-linux.img (the microcode hook from Step 12.5), so no separate image is mentioned - that's normal and correct. Older-style setups show a line like Found initrd image: /boot/intel-ucode.img /boot/initramfs-linux.img instead. Either way, your CPU microcode loads at every boot.

πŸ”— If the machine later boots to a black screen or a grub rescue> prompt instead of a menu - jump straight to Troubleshooting β†’ GRUB rescue below. The chroot-back pattern there fixes bootloader mistakes without reinstalling.

Dual-Booting Windows/Linux Alongside?

Install the detector and let GRUB list other OSes:

BASH SnippetBASH
pacman -S os-prober
nano /etc/default/grub        # add/uncomment: GRUB_DISABLE_OS_PROBER=false
grub-mkconfig -o /boot/grub/grub.cfg

14. Final Steps and Reboot

Enable networking so Wi-Fi works after reboot:

BASH SnippetBASH
systemctl enable NetworkManager

(Case matters: NetworkManager, capital N and M. A lowercase typo silently creates a broken unit name.)

Then perform the launch sequence:

BASH SnippetBASH
exit                # leave chroot back to live environment
umount -R /mnt      # unmount everything recursively
reboot              # πŸš€

Pull the USB out as soon as the screen goes dark (or when prompted), so it doesn't boot back into the installer.


15. First Login Checklist

The machine reboots β†’ GRUB menu flashes by β†’ a text login prompt greets you:

TEXT SnippetTEXT
myarchlaptop login: _

Log in with your username (not root). Then run through:

1. Test sudo:

BASH SnippetBASH
sudo whoami

Should print root.

2. Connect to Wi-Fi (NetworkManager replaces iwctl now):

BASH SnippetBASH
nmcli device wifi list
nmcli device wifi connect "YourWiFiName" password "yourpassword"

Ethernet users: already connected, skip ahead.

3. Update the system (first thing, always):

BASH SnippetBASH
sudo pacman -Syu

4. Verify microcode loaded:

BASH SnippetBASH
dmesg | grep microcode

Congratulations. You built a working Linux system with your own hands. πŸ†

Where To Next?

Your system is barebones-on-purpose. Here's the standard post-install tour, roughly in the order most people do it:

GoalDo This
Fallback kernel (survive a bad update)sudo pacman -S linux-lts then sudo grub-mkconfig -o /boot/grub/grub.cfg - GRUB will offer it at boot
SSD healthsudo systemctl enable fstrim.timer (weekly TRIM for your ext4 root)
AUR helper (yay/paru)base-devel is already installed - clone from AUR and makepkg -si, then yay -S anything
GPU acceleration / gaming prepmesa + vulkan-* drivers (AMD/Intel), or nvidia (proprietary). Steam/Wine also need [multilib] uncommented in /etc/pacman.conf
Audiosudo pacman -S pipewire pipewire-pulse pipewire-alsa wireplumber - the modern audio stack, no config needed
Fonts that don't look brokensudo pacman -S ttf-dejavu ttf-liberation noto-fonts
A firewall (none exists by default)sudo pacman -S ufw β†’ sudo ufw default deny && sudo ufw enable
Standard home folderssudo pacman -S xdg-user-dirs β†’ run xdg-user-dirs-update

Then pick your desktop from the classics below:

WantInstall
Full desktop, works out of the boxsudo pacman -S gnome gdm β†’ sudo systemctl enable gdm
Slick modern tiling Wayland compositorsudo pacman -S hyprland kitty waybar
Lightweight classic tilingsudo pacman -S i3-wm i3status dmenu xorg-server

Two bigger forks in the road this guide didn't cover, so you know they exist:

  • Snapshots & rollback: on a rolling distro, being able to undo a bad update is gold. That's the killer feature of Btrfs with snapper or timeshift - worth considering for your next install.
  • Full-disk encryption (LUKS): if you want your data encrypted at rest (laptop users, take note), partitioning and boot setup differ substantially. Follow the ArchWiki dm-crypt guide from the start.

Surviving a Rolling Release

The #1 mistake new Arch users make: install once, ignore updates for months, then run one massive upgrade that breaks everything. Avoid the pain:

  • Update weekly at minimum - small diffs are easy to debug.
  • Never partial-upgrade. pacman -Sy <package> installs against stale metadata and corrupts your system. Always pacman -Syu.
  • Check archlinux.org/news before updating. Manual-intervention notices appear there first.
  • Broke something anyway? The fix is almost always already documented in that news feed, the ArchWiki, or the forums. With linux-lts installed you have a known-good kernel to boot into while you work it out.

16. Troubleshooting

Every failure below has been hit by thousands of Arch users. Find yours:

❓ "No such file or directory" for /sys/firmware/efi/efivars

You booted in Legacy/CSM mode, not UEFI. Reboot β†’ firmware settings β†’ disable CSM/Legacy Boot β†’ boot the USB through its UEFI: entry (Step 4).

❓ iwctl says "No such device" / no wlan0

Radio may be soft-blocked: rfkill unblock all, then re-run iwctl. Still nothing? Some laptops have a physical airplane-mode switch/Fn-key - flip it. Worst case your Wi-Fi card needs firmware that linux-firmware provides - it's included in the live ISO, so if it still fails, use a phone's USB tethering or Ethernet to finish installing, then troubleshoot after.

❓ ping archlinux.org fails but iwctl said connected

Run ip link - is the interface UP? Try dhcpcd manually if needed. DNS issue test: ping -c 3 1.1.1.1. IP works but domain doesn't β†’ DNS problem; simplest fix: reconnect the station in iwctl.

❓ Formatted the WRONG disk/partition

Stop immediately. Data may still be recoverable with tools like testdisk/photorec as long as you don't write anything else to that disk. This is why we triple-checked names in Step 7.

❓ pacman signature/keyring errors during pacstrap

Usually a stale clock. timedatectl set-ntp true, wait for sync, retry. Persistent cases: pacman-key --init && pacman-key --populate archlinux in the live env, then rerun pacstrap with -K.

❓ Machine reboots to black screen / GRUB rescue prompt

Bootloader misconfigured. Boot the live USB again, remount, and chroot back:

BASH SnippetBASH
mount /dev/nvme0n1p3 /mnt
mount /dev/nvme0n1p1 /mnt/boot
swapon /dev/nvme0n1p2
mount /dev/nvme0n1p4 /mnt/home   # only if you created a /home partition
arch-chroot /mnt
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
grub-mkconfig -o /boot/grub/grub.cfg
exit
umount -R /mnt
reboot

This chroot-back pattern fixes ANY mistake made in Steps 12-13. Bookmark it.

❓ Boots but drops to emergency shell mentioning fstab

Typo in /etc/fstab. In the emergency shell: mount -o remount,rw /, open /etc/fstab, fix the bad UUID/path, reboot.

❓ Forgot to enable NetworkManager / set something in chroot

Same recovery pattern as above: live USB β†’ mount β†’ arch-chroot /mnt β†’ do the missed step (systemctl enable NetworkManager, passwd, whatever) β†’ exit β†’ reboot.

❓ Wi-Fi worked in installer, dead after first boot

NetworkManager wasn't enabled. Chroot back (pattern above) and run systemctl enable NetworkManager.


17. Complete Command Cheat Sheet

The entire install, compressed. For when you've done it before and just want the run-through:

BASH SnippetBASH
# ─── Live environment ────────────────────────────────
ls /sys/firmware/efi/efivars        # verify UEFI
iwctl                               # Wi-Fi: station wlan0 connect "SSID"
ping -c 3 archlinux.org             # verify internet
timedatectl set-ntp true            # fix clock
lsblk                               # identify disk (nvme0n1 or sda!)

# ─── Partition (choose ONE method) ───────────────────
cfdisk /dev/nvme0n1                 # GUI-ish: 512M EFI / 4G swap / 60G root / rest /home
fdisk /dev/nvme0n1                  # CLI: g,n,+512M,t,1 | n,+4G,t,19 | n,+60G | n,⏎,⏎ | w
# (skip the /home partition? let root = rest of disk: fdisk ... | n,⏎,⏎ | w)

# ─── Format & mount ──────────────────────────────────
mkfs.fat -F32 /dev/nvme0n1p1
mkswap /dev/nvme0n1p2
mkfs.ext4 /dev/nvme0n1p3
mkfs.ext4 /dev/nvme0n1p4            # ONLY if you created a /home partition
swapon /dev/nvme0n1p2
mount /dev/nvme0n1p3 /mnt
mkdir -p /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot
mkdir -p /mnt/home
mount /dev/nvme0n1p4 /mnt/home     # ONLY if you created a /home partition

# ─── Install base ────────────────────────────────────
nano /etc/pacman.d/mirrorlist      # paste list from archlinux.org/mirrorlist & uncomment servers
reflector --latest 20 --sort rate --save /etc/pacman.d/mirrorlist   # or: auto-sort instead
pacstrap -K /mnt base linux linux-firmware vim nano networkmanager intel-ucode amd-ucode base-devel man-db man-pages texinfo
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab                  # VERIFY 3 entries (4 if you made /home)!

# ─── Configure (inside arch-chroot /mnt) ─────────────
arch-chroot /mnt
ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc
nano /etc/locale.gen                # uncomment en_US.UTF-8 UTF-8
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
echo "myarchlaptop" > /etc/hostname
nano /etc/hosts                     # localhost lines + hostname line
passwd                              # root password
useradd -m -G wheel -s /bin/bash yourusername
passwd yourusername
EDITOR=nano visudo                  # uncomment %wheel ALL=(ALL:ALL) ALL
pacman -S grub efibootmgr
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
blkid /dev/nvme0n1p2                # hibernation only: put resume=UUID=<swap> in /etc/default/grub
grub-mkconfig -o /boot/grub/grub.cfg
systemctl enable NetworkManager

# ─── Launch ──────────────────────────────────────────
exit
umount -R /mnt
reboot

Conclusion

Take a second to appreciate what you just configured by hand: a GPT partition table, a UEFI System Partition, swap, an ext4 root filesystem, fstab, locale, timezone, hostname, a user with sudo, a bootloader, and a network manager. Most distributions hide all of that behind a "Next" button - you built every layer yourself.

That's why you won't panic when something breaks six months from now. You'll chroot in and fix it, because there's no layer of this machine you haven't seen.

From here, install a window manager, rice your terminal, and join the ranks of people whose answer to "what OS do you run?" ends conversations:

"I use Arch btw."

Sources & further reading: the official ArchWiki Installation Guide, GRUB page, and General Recommendations - the best documentation in all of Linux.

Share this post

Related Articles