Skip to main content
UCI (Unified Configuration Interface) is OpenWrt’s centralized configuration system. All system configuration is stored in plain-text files under /etc/config/, and the uci command-line tool and libuci library provide a consistent API for reading and modifying these files.

Architecture

ComponentPackageDescription
libucilibuciC library for reading/writing UCI config files
uciuciCommand-line utility
libuci-lualibuci-luaLua bindings for libuci
Configuration files live in /etc/config/. Each file represents a configuration domain (e.g., network, system, firewall, wireless).

UCI File Format

# /etc/config/system

config system
    option hostname 'OpenWrt'
    option timezone 'UTC'
    option log_size '64'

config timeserver 'ntp'
    option enabled '1'
    list server '0.openwrt.pool.ntp.org'
    list server '1.openwrt.pool.ntp.org'
Key syntax elements:
KeywordSyntaxDescription
configconfig <type> [<name>]Start a new section. <name> is optional (anonymous sections get auto-names like cfg123456).
optionoption <name> '<value>'Set a single string value.
listlist <name> '<value>'Append a value to a list option. Multiple list lines with the same name create a list.

Full CLI Reference

Reading Configuration

# Show all options in a config file (UCI path format)
uci show system

# Show a specific section
uci show system.ntp

# Get a single option value
uci get system.@system[0].hostname
uci get system.ntp.enabled

# Export config in UCI syntax (machine-readable)
uci export network

# Export all config files
uci export

Writing Configuration

# Set an option (staged, not yet written to disk)
uci set system.@system[0].hostname='MyRouter'

# Add a new unnamed section
uci add firewall rule

# Set an option in a named section
uci set network.loopback.ipaddr='127.0.0.1'

# Append to a list
uci add_list system.ntp.server='2.openwrt.pool.ntp.org'

# Delete an option
uci delete system.@system[0].log_size

# Delete an entire section
uci delete network.wan6

# Rename a section
uci rename firewall.@rule[0]=my_ssh_rule

# Commit staged changes to disk
uci commit

# Commit only one config file
uci commit system

# Discard staged changes
uci revert system

Batch Mode

# Read UCI commands from stdin
uci batch <<EOF
set system.@system[0].hostname='NewHostname'
set system.@system[0].timezone='CET-1CEST,M3.5.0,M10.5.0/3'
commit system
EOF

Import

# Import a UCI-format config file
uci import network < my-network-config.uci

Transaction Model

UCI uses a staged commit model:
  1. uci set / uci add / uci delete write changes to a temporary overlay in /tmp/.uci/
  2. uci commit atomically writes the changes to /etc/config/
  3. uci revert discards the staged changes
This means that changes are not visible to running daemons until after commit and the relevant daemon is reloaded.

Practical Examples

Set the Hostname

uci set system.@system[0].hostname='my-router'
uci commit system
/etc/init.d/system reload

Configure a Static LAN IP

uci set network.lan.ipaddr='10.0.0.1'
uci set network.lan.netmask='255.255.255.0'
uci commit network
/etc/init.d/network restart

Add a Firewall Rule

RULE=$(uci add firewall rule)
uci set firewall.${RULE}.name='Allow-SSH'
uci set firewall.${RULE}.src='wan'
uci set firewall.${RULE}.dest_port='22'
uci set firewall.${RULE}.proto='tcp'
uci set firewall.${RULE}.target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart

Read Config in a Shell Script

#!/bin/sh
HOSTNAME=$(uci get system.@system[0].hostname 2>/dev/null)
echo "Hostname: ${HOSTNAME:-unknown}"

UCI Path Syntax

UCI addresses follow the format:
<config>.<section>.<option>
PathRefers to
networkEntire network config file
network.lanSection named lan in network
network.lan.ipaddrOption ipaddr inside section lan
network.@interface[0]First anonymous section of type interface
network.@interface[-1]Last anonymous section of type interface

Build docs developers (and LLMs) love