How to List Installed Packages on Debian with apt and dpkg

By 

Updated on

9 min read

List Installed Packages with apt and dpkg on Debian

Knowing how to list installed packages on your Debian system is useful when you need to replicate the same setup on another machine, audit what is installed, or troubleshoot dependency issues.

This guide explains how to list, filter, and count installed packages on Debian using apt, dpkg-query, and apt-mark. The commands work on Debian 13 and older supported Debian releases. Listing commands only read the local package database, so they do not need sudo.

Quick Reference

TaskCommand
List all installed packagesapt list --installed
Check if a package is installedapt list --installed package_name
Filter installed packagesapt list --installed 2>/dev/null | grep '^package_name/'
Show installed package versiondpkg-query -W -f='${db:Status-Abbrev} ${Version}\n' package_name | awk '$1 == "ii" { print $2 }'
List manually installed packagesapt-mark showmanual
Count installed packagesdpkg-query -W -f='${db:Status-Abbrev}\n' | awk '$1 == "ii" { count++ } END { print count }'
Find the largest packagesdpkg-query -W -f='${db:Status-Abbrev} ${Installed-Size}\t${binary:Package}\n' | awk '$1 == "ii" { print $2 "\t" $3 }' | sort -rn | head
See when a package was installedgrep " install " /var/log/dpkg.log
Export manual package listapt-mark showmanual > manual-packages.txt

For a printable quick reference, see the apt cheatsheet and the dpkg cheatsheet .

List Installed Packages with apt

The apt command provides a straightforward way to list installed packages during interactive work:

Terminal
apt list --installed
output
adduser/trixie,now 3.152 all [installed]
apt/trixie,now 3.0.3 amd64 [installed]
base-files/trixie,now 13.8+deb13u5 amd64 [installed]
bash/trixie,now 5.2.37-2+b9 amd64 [installed]
coreutils/trixie,now 9.7-3 amd64 [installed]
...

The output shows the package name, release channel, version, architecture, and installation status. Packages marked [installed,automatic] were installed as dependencies of another package.

Since the list is long, you can pipe the output to less for easier reading:

Terminal
apt list --installed | less

Check a Specific Package

To check whether a specific package is installed, pass the package name to apt list --installed:

Terminal
apt list --installed nginx
output
nginx/trixie,now 1.26.3-3+deb13u7 amd64 [installed]

For a broader search, pipe the installed package list to grep :

Terminal
apt list --installed 2>/dev/null | grep '^nginx/'

The 2>/dev/null suppresses the apt stability warning that appears when piping. For scripts and repeatable exports, use dpkg-query because its formatted output is more stable.

Show the Installed Version

To print only the installed version of a package, use dpkg-query:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${Version}\n' nginx | awk '$1 == "ii" { print $2 }'
output
1.26.3-3+deb13u7

Show Package Details

A version number does not tell you what a package does or what it drags in with it. To see the description, dependencies, and download size, use apt show:

Terminal
apt show nginx
output
Package: nginx
Version: 1.26.3-3+deb13u7
Priority: optional
Section: httpd
Installed-Size: 1,551 kB
Depends: nginx-common (= 1.26.3-3+deb13u7), libc6 (>= 2.34), libcrypt1 (>= 1:4.1.0), ...
Homepage: https://nginx.org
Description: small, powerful, scalable web/proxy server

apt show reads repository metadata, so it also works for packages you have not installed yet. When you want the state dpkg recorded on this particular machine, use dpkg -s:

Terminal
dpkg -s nginx
output
Package: nginx
Status: install ok installed
Priority: optional
Section: httpd
Installed-Size: 1551
Version: 1.26.3-3+deb13u7

The Status: install ok installed line is the definitive answer to whether the package is installed and configured. A package that was removed without purging shows deinstall ok config-files instead.

List Installed Packages with dpkg-query

The dpkg-query command queries the dpkg database directly and offers more formatting options than apt.

To view the packages recorded in the dpkg database and their status:

Terminal
dpkg-query -l
output
||/ Name           Version        Architecture Description
+++-==============-==============-============-=================================
ii  adduser        3.152          all          add and remove users and groups
ii  apt            3.0.3          amd64        commandline package manager
ii  base-files     13.8+deb13u5   amd64        Debian base system misc files
ii  bash           5.2.37-2+b9    amd64        GNU Bourne Again SHell
...

This listing can also include removed packages whose configuration files remain. The ii at the beginning of a line means that the package is installed, while rc identifies a removed package with configuration files left behind. The remaining columns show the package name, version, architecture, and a short description.

To check a specific package:

Terminal
dpkg-query -l nginx

Custom Output Format

You can control the output format with the -f option. For example, to print only package names and versions:

Terminal
dpkg-query -W -f='${binary:Package} ${Version}\n'

For an installed-only package name list, include the dpkg status abbreviation and filter for ii, which means the package is installed:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | awk '$1 == "ii" { print $2 }'

Find Packages That Are Not Fully Installed

The status field is just as useful in reverse. To catch packages that are not in the normal ii state, invert the filter:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | awk '$1 != "ii" { print }'
output
rc  libpng12-0
rc  python3-six

The rc status means the package itself was removed but its configuration files are still on disk. Those leftovers are harmless, and they explain why a package name keeps appearing in queries after you thought you had removed it. Run sudo apt purge package_name to clear them out.

List Manually Installed Packages

The apt-mark showmanual command lists packages marked as manually installed, excluding packages marked as automatic dependencies:

Terminal
apt-mark showmanual

This is particularly useful when you want to recreate your system on a new machine. Manual packages are a better starting point than every dependency, but the list can include base packages marked manual during installation.

Find the Largest Installed Packages

When a Debian system starts running out of disk space, the package database can help identify large packages. Filter for the ii status before sorting on Installed-Size so removed packages do not appear in the results:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${Installed-Size}\t${binary:Package}\n' | awk '$1 == "ii" { print $2 "\t" $3 }' | sort -rn | head -10

The first column is the approximate installed size in KiB, which gets hard to read once packages reach into the hundreds of megabytes. Pipe that column through numfmt to convert it to human-readable IEC units:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${Installed-Size}\t${binary:Package}\n' | awk '$1 == "ii" { print $2 "\t" $3 }' | sort -rn | head -10 | numfmt --field=1 --from-unit=1024 --to=iec

Installed-Size is an approximate figure declared in the package metadata, not a live measurement of the files on disk. It is useful for rough comparisons, but it will not match what du reports for the same files.

Export and Restore Package Lists

To save only manually installed packages to a file:

Terminal
apt-mark showmanual > manual-packages.txt

To install those packages on another Debian system:

Terminal
sudo apt update
sudo xargs -a manual-packages.txt apt install

This installs fewer packages and lets apt resolve dependencies automatically.

If you need a full installed package list for auditing, export installed package names with dpkg-query:

Terminal
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | awk '$1 == "ii" { print $2 }' > packages.txt

Restoring a full package list works best on the same Debian release and architecture with the same repositories enabled. Packages may fail to install on a different release if names changed, packages were removed, or third-party repositories are missing.

Debian has an older mechanism for the same job, and you will still run into it in provisioning scripts and older documentation. The dpkg command can dump the package selection state to a file:

Terminal
dpkg --get-selections > selections.txt

To replay it on another machine:

Terminal
sudo apt update
apt-cache dumpavail | sudo dpkg --merge-avail
sudo dpkg --set-selections < selections.txt
sudo apt-get dselect-upgrade

The apt-cache pipeline updates dpkg’s available-package database so --set-selections does not ignore packages that are unknown on the destination system. --set-selections then marks the packages for installation, and apt-get dselect-upgrade does the actual downloading and installing. The apt-mark list above is easier to read and edit by hand, so prefer it unless you specifically need the selection format.

View Install History

The current package list tells you what is installed now, but sometimes you need to see when packages were installed or upgraded. Debian records APT actions in /var/log/apt/history.log:

Terminal
less /var/log/apt/history.log

Older logs may be compressed. Use zgrep to search all history files for install actions:

Terminal
zgrep "^Install:" /var/log/apt/history.log*

That history only covers actions taken through apt and apt-get. Anything installed directly with dpkg -i never touches it. For a complete record of every package operation on the system, read /var/log/dpkg.log:

Terminal
grep " install " /var/log/dpkg.log
output
2026-08-19 09:14:02 install nginx:amd64 <none> 1.26.3-3+deb13u7
2026-08-19 09:14:05 install nginx-common:all <none> 1.26.3-3+deb13u7
2026-08-27 18:02:41 install htop:amd64 <none> 3.3.0-4

Each line starts with a timestamp, so the newest installs are at the bottom. The two trailing columns are the previous and new versions, and <none> marks a package that was not on the system before. Swap install for upgrade or remove to trace those actions instead. Older entries rotate into compressed files, so use zgrep " install " /var/log/dpkg.log* when you need the full history.

Count Installed Packages

To find out how many packages are installed on your system, count packages whose dpkg status is ii:

Terminal
dpkg-query -W -f='${db:Status-Abbrev}\n' | awk '$1 == "ii" { count++ } END { print count }'
output
487

To count only manually installed packages:

Terminal
apt-mark showmanual | wc -l

Troubleshooting

apt prints a warning about unstable CLI output
This warning appears when using apt in scripts or piped commands. For scripted exports and automation, prefer dpkg-query because its output format is more stable.

Some packages fail to install on the new system
The destination system may use different repositories, architecture, or release versions. Run sudo apt update, verify your enabled repositories, and install missing third-party repositories before replaying the package list.

xargs restore command fails with permission errors
Package installation requires administrative privileges. Use sudo with the install command and ensure your user has sudo access.

FAQ

What is the difference between apt list and dpkg-query?
apt list --installed provides user-friendly output with release channel information. dpkg-query reads the dpkg database directly and offers more control over the output format. When you filter dpkg-query results for the ii status, both commands report the same installed package set.

How do I check the version of an installed package?
Use apt list --installed package_name or dpkg-query -W -f='${db:Status-Abbrev} ${Version}\n' package_name | awk '$1 == "ii" { print $2 }' to display the installed version.

What does [installed,automatic] mean in the apt list output?
It means the package was automatically installed as a dependency of another package, not explicitly requested by the user.

How do I list packages that need updates?
Run apt update to refresh the package list, then use apt list --upgradable to see packages with available updates.

How do I remove a package from the system?
Use apt remove package_name to remove the package while keeping its configuration files, or apt purge package_name to remove everything including configuration files.

Conclusion

You can list installed packages on Debian using apt list --installed for a quick overview, dpkg-query for custom formatting, and apt-mark showmanual for packages marked as manually installed. Export the manual list when rebuilding a system, and use the APT history log when you need to see when packages were installed or upgraded.

For more package management commands, see the guide on using the apt command .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page