Skip to main content
This guide takes you from a clean Linux or macOS machine to a working OpenWrt firmware image ready to flash on your device.
OpenWrt requires a case-sensitive filesystem. macOS users must build inside a case-sensitive disk image or volume. Cygwin and WSL1 are not supported — use WSL2 with a native Linux filesystem, or a Linux VM.

Prerequisites

Before you begin, ensure your system meets the requirements. Install the build dependencies for your distribution:
sudo apt update
sudo apt install -y \
  binutils bzip2 diff flex gawk gcc \
  getopt grep install-info libc-dev \
  libz-dev make perl python3 rsync \
  subversion unzip which
You need at least 15 GB of free disk space and 4 GB of RAM. The first build downloads source archives and compiles a complete cross-compilation toolchain, which takes 30–90 minutes on modern hardware.

Build your firmware

1

Clone the repository

Clone OpenWrt from GitHub and enter the directory:
git clone https://github.com/openwrt/openwrt.git
cd openwrt
To build a specific stable release instead of the development branch:
git tag -l 'v*'          # list available release tags
git checkout v23.05.3    # check out a release tag
2

Update and install feeds

Feeds are external package repositories. Update their package lists and create symlinks for all packages:
./scripts/feeds update -a
./scripts/feeds install -a
This populates package/feeds/ with symlinks to all feed packages, making them available in menuconfig.
3

Configure your build

Launch the interactive configuration menu:
make menuconfig
At minimum, select:
  • Target System — the CPU architecture (e.g., Atheros ATH79, MediaTek Ralink MIPS, x86)
  • Subtarget — the specific SoC or board family
  • Target Profile — your specific router model
Use Space to toggle options:
  • [*] — built into the firmware image
  • [M] — compiled as a separate .ipk installable package
  • [ ] — excluded
Save with S, then exit with Q.
Use the / key in menuconfig to search for a specific package or config option by name.
4

Build

Start the build with parallel jobs:
make -j$(nproc)
For verbose output useful when troubleshooting:
make -j$(nproc) V=s 2>&1 | tee build.log
The build compiles in this order:
  1. Host tools (e.g., mkimage, mksquashfs)
  2. Cross-compilation toolchain (GCC + musl libc)
  3. Linux kernel for your target
  4. All selected packages
  5. Firmware image assembly
5

Find your firmware image

After a successful build, images are in:
bin/targets/<target>/<subtarget>/
For example, for an Atheros ATH79 generic target:
bin/targets/ath79/generic/
├── openwrt-ath79-generic-<device>-squashfs-factory.bin   # flash from vendor firmware
├── openwrt-ath79-generic-<device>-squashfs-sysupgrade.bin # upgrade from OpenWrt
└── packages/                                              # compiled package repo
  • Use the factory image to flash from the vendor firmware for the first time.
  • Use the sysupgrade image to upgrade an existing OpenWrt installation.

Rebuild a single package

After the initial build, you can recompile just one package without rebuilding everything:
make package/<name>/compile V=s
For example, to recompile curl:
make package/curl/compile V=s

Clean the build

CommandWhat it removes
make cleanBuild output (build_dir/, bin/)
make dircleanEverything clean removes, plus the cross-toolchain and host tools in staging_dir/
make distcleanEverything dirclean removes, plus .config*, dl/ (downloaded sources), feeds/, and signing keys
make distclean removes your .config file and all downloaded source archives. Save your config first: cp .config my-config.backup.

Next steps

Build System

Understand the full build pipeline and available make targets

Supported Devices

Find your device and check supported features

Package Development

Create and port packages to OpenWrt

Core Concepts

Learn the OpenWrt architecture and subsystems

Build docs developers (and LLMs) love