What Is the Difference Between apt and apt-get?

apt and apt-get are both command-line tools for managing packages on Debian and Ubuntu Linux, but they serve different purposes. apt (introduced in Ubuntu 14.04 / Debian 8) is designed for interactive terminal use — it has a simpler interface, progress bars, colored output, and combines the most common commands from apt-get and apt-cache into one tool. apt-get is the older, more stable tool intended for scripts and automation because its output format is guaranteed not to change between versions. For everyday use in the terminal, use apt. For shell scripts, use apt-get.

Two Tools, One Job, Different Purposes

If you have spent any time following Linux tutorials, you have almost certainly encountered both apt install and apt-get install for installing software. Both commands work. Both are present on Ubuntu and Debian systems. Both install the same packages from the same repositories. Yet they are different tools with different designs, different behaviors, and different appropriate use cases.

The existence of both commands often confuses Linux newcomers: which should I use? Are they interchangeable? Is one newer and better? Why do some tutorials use one and some use the other?

The answer is clear once you understand the design intent behind each tool. apt-get came first — it is the original APT (Advanced Package Tool) frontend that has been part of Debian since 1998. apt was introduced much later (2014 on Ubuntu, Debian 8 in 2015) as a purpose-built tool for human interactive use. The two tools have different design goals: apt-get prioritizes stability and scriptability, while apt prioritizes the interactive user experience.

This article explains the technical differences between them, what commands map between the two, when to use each, and the broader APT tool ecosystem — including apt-cache, apt-file, dpkg, and others that serve specialized roles.

The APT Tool Family

Before comparing apt and apt-get specifically, understanding the full family of APT-related tools provides essential context.

The Advanced Package Tool (APT) is not a single program — it is a library (libapt) with multiple frontend programs built on top of it:

apt-get — the original command-line frontend for package installation and management. Designed in 1998. Stable, scriptable, widely documented.

apt-cache — a separate tool for querying the package cache: searching for packages, showing package information, listing dependencies. Designed alongside apt-get.

apt-file — searches for which package provides a specific file. Requires installation: sudo apt install apt-file.

apt — a unified, user-friendly frontend combining the most-used features of apt-get and apt-cache into a single command with improved output. Designed for humans using the terminal interactively. Introduced in 2014.

apt-mark — marks packages as automatically or manually installed, or holds packages from being upgraded.

apt-config — queries APT configuration.

aptitude — a full-featured, interactive text-based package manager. More powerful than apt for complex dependency situations.

The key insight: apt and apt-get are different interfaces to the same underlying APT library. They can both install the same packages, but they are designed for different contexts.

apt vs. apt-get: The Key Differences

1. Design Goal: Human vs. Script

apt is explicitly documented as being designed for end users interacting with the terminal directly. From the apt(8) man page: “The apt command is meant to be pleasant for end users and does not need to be backward compatible.” This freedom to change output format and behavior without worrying about breaking scripts is what enables its improved user experience.

apt-get is documented for use in scripts and automation. The apt-get(8) man page notes that its behavior and output format are stable and will not change in incompatible ways between versions. Scripts that process apt-get output can rely on that output remaining consistent.

2. Progress Bar

apt shows a visual progress bar during downloads and installations:

Get:1 http://archive.ubuntu.com/ubuntu noble/main amd64 vim amd64 2:9.1.0016-1ubuntu7 [1,757 kB]
Fetched 1,757 kB in 1s (2,341 kB/s)
(Reading database ... 186429 files and directories currently installed.)
Preparing to unpack .../vim_2%3a9.1.0016-1ubuntu7_amd64.deb ...
Unpacking vim (2:9.1.0016-1ubuntu7) ...
[####################] 100%

apt-get shows no progress bar — just text output:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  vim
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,757 kB of archives.
After this operation, 4,058 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu noble/main amd64 vim amd64 2:9.1.0016-1ubuntu7 [1,757 kB]
Fetched 1,757 kB in 1s (2,341 kB/s)

3. Colored Output

apt uses color to make output easier to scan — package names in a different color, warnings in yellow or orange, errors in red.

apt-get produces plain text without color coding.

4. Upgrade Command Behavior

apt upgrade — equivalent to apt-get upgrade but with slightly more informative output.

apt full-upgrade — equivalent to apt-get dist-upgrade. The name change is significant: apt full-upgrade communicates more clearly that this is a more aggressive upgrade that may remove packages. apt-get dist-upgrade had a confusing name that suggested distribution-level upgrade, when it is really just a more complete local upgrade.

5. Number of Packages Pending

apt shows a count of upgradable packages at the end of apt update:

$ sudo apt update
...
12 packages can be upgraded. Run 'apt list --upgradable' to see them.

apt-get update does not show this summary.

6. apt list vs. dpkg -l

apt introduces apt list — a cleaner way to list packages:

$ apt list --installed          # All installed packages
$ apt list --upgradable         # Packages with available upgrades
$ apt list --all-versions       # All versions of all packages
$ apt list vim                  # Information about a specific package

apt-get does not have a list command — you use dpkg -l instead.

7. Combined Search and Info (replaces apt-cache)

apt search and apt show replace separate apt-cache search and apt-cache show commands:

# With apt:
$ apt search nginx
$ apt show nginx

# With older tools:
$ apt-cache search nginx
$ apt-cache show nginx

Both approaches work on modern systems, but apt provides a single tool.

Command Mapping: apt vs. apt-get/apt-cache

apt apt-get / apt-cache What it does
apt update apt-get update Refresh package lists
apt upgrade apt-get upgrade Install available upgrades
apt full-upgrade apt-get dist-upgrade Upgrade with dependency changes
apt install pkg apt-get install pkg Install a package
apt remove pkg apt-get remove pkg Remove package (keep config)
apt purge pkg apt-get purge pkg Remove package + config files
apt autoremove apt-get autoremove Remove unneeded dependencies
apt clean apt-get clean Remove downloaded package files
apt autoclean apt-get autoclean Remove outdated downloaded files
apt search term apt-cache search term Search for packages
apt show pkg apt-cache show pkg Show package details
apt list --installed dpkg -l List installed packages
apt list --upgradable apt-get -s upgrade List upgradable packages
apt edit-sources nano /etc/apt/sources.list Edit package sources
— apt-get build-dep pkg Install build dependencies
— apt-get source pkg Download package source

Notable gaps in apt: A few apt-get operations do not have apt equivalents — build-dep and source are the most common. For these, use apt-get directly even when you normally use apt.

When to Use apt vs. apt-get

Use apt for Interactive Terminal Sessions

When you are typing commands in a terminal and want:

  • The progress bar during downloads
  • Colored output for easier reading
  • The handy “N packages can be upgraded” reminder after apt update
  • A single tool for both installation and searching
$ sudo apt update && sudo apt upgrade
$ sudo apt install vim curl git
$ apt search pdf viewer
$ apt show evince
$ apt list --upgradable

This is the appropriate default for everyday Linux use.

Use apt-get in Shell Scripts

When writing scripts that:

  • Parse command output (the format of apt-get output is stable)
  • Run in automated/unattended environments (CI/CD pipelines, Ansible playbooks, Docker containers)
  • Need -y to auto-confirm without interaction
  • May run on older Ubuntu/Debian versions (before apt was available)
#!/bin/bash
# In a script, use apt-get for stability
sudo apt-get update -q
sudo apt-get install -y -q vim curl git

# Check exit codes reliably
if ! apt-get install -y nginx; then
    echo "Failed to install nginx"
    exit 1
fi

The -q (quiet) flag reduces output for scripts. The -y flag auto-confirms prompts.

Docker example (seen in virtually every Dockerfile):

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
    && rm -rf /var/lib/apt/lists/*

Docker conventions use apt-get because Dockerfiles are automation, --no-install-recommends reduces image size, and rm -rf /var/lib/apt/lists/* removes the package cache to minimize image size.

Common apt and apt-get Operations Explained

Update Package Lists

$ sudo apt update
# or
$ sudo apt-get update

This downloads the latest package index from configured repositories. It does not install or upgrade anything — it only refreshes your local list of available packages and versions. Always run this before installing packages or checking for upgrades.

Install Packages

$ sudo apt install packagename
$ sudo apt install package1 package2 package3    # Multiple packages
$ sudo apt install ./local_package.deb           # Install a local .deb file

Remove Packages

$ sudo apt remove packagename         # Remove package, keep configuration files
$ sudo apt purge packagename          # Remove package AND configuration files
$ sudo apt autoremove                 # Remove orphaned dependencies
$ sudo apt autoremove --purge         # Remove orphaned packages and their configs

When to use remove vs. purge: Use remove when you might want to reinstall the package later (keeping config means you do not have to reconfigure from scratch). Use purge when you want a clean removal — no leftover config files.

Upgrade Packages

$ sudo apt upgrade                    # Upgrade packages without removing others
$ sudo apt full-upgrade               # Upgrade, adding/removing packages as needed

The difference: apt upgrade will not remove any installed package to satisfy an upgrade. apt full-upgrade (or apt-get dist-upgrade) will remove packages if necessary to complete upgrades — useful for major dependency changes.

For routine security updates and regular updates, apt upgrade is appropriate. For distribution point releases or major changes, apt full-upgrade may be needed.

Searching and Browsing Packages

$ apt search keyword                  # Search package names and descriptions
$ apt search "web server"             # Multi-word search
$ apt show packagename                # Detailed package information
$ apt list --installed                # All installed packages
$ apt list --installed | grep nginx   # Check if nginx is installed
$ apt list --upgradable               # Packages with available upgrades

Fixing Broken Package States

$ sudo apt install -f                 # Fix broken dependencies
$ sudo apt --fix-broken install       # Alternative syntax
$ sudo dpkg --configure -a            # Configure any unpacked but unconfigured packages

The -y Flag and Unattended Operation

For scripted use, the -y (yes) flag automatically confirms prompts:

$ sudo apt-get install -y vim         # Install without prompting
$ sudo apt-get remove -y packagename  # Remove without prompting

Caution with -y in interactive use: Using -y interactively means you will not see what packages are about to be removed or installed. Always review the summary before confirming manually in interactive sessions. Save -y for scripts where you have already tested the command.

For full unattended operation in scripts (suppressing all interactive prompts including configuration dialogs):

DEBIAN_FRONTEND=noninteractive apt-get install -y packagename

DEBIAN_FRONTEND=noninteractive prevents package post-install scripts from asking configuration questions — essential for automated installation in containers and CI pipelines.

apt-cache: The Query Tool

Even after apt was introduced, apt-cache remains useful for operations not covered by apt:

$ apt-cache depends nginx             # What packages does nginx depend on?
$ apt-cache rdepends nginx            # What packages depend on nginx?
$ apt-cache policy nginx              # Which repository a package comes from, versions available
$ apt-cache madison nginx             # All available versions of nginx
$ apt-cache pkgnames | grep python    # List all available packages matching pattern

apt-cache policy is particularly useful for diagnosing why a specific version of a package is installed:

$ apt-cache policy nginx
nginx:
  Installed: 1.24.0-2ubuntu7
  Candidate: 1.24.0-2ubuntu7
  Version table:
 *** 1.24.0-2ubuntu7 500
        500 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages

apt-mark: Controlling Package States

apt-mark manages package metadata:

$ sudo apt-mark hold packagename       # Prevent a package from being upgraded
$ sudo apt-mark unhold packagename     # Allow upgrades again
$ sudo apt-mark showhold               # List held packages

$ sudo apt-mark manual packagename     # Mark as manually installed (won't be autoremoved)
$ sudo apt-mark auto packagename       # Mark as automatically installed (eligible for autoremove)
$ sudo apt-mark showauto               # List automatically installed packages
$ sudo apt-mark showmanual             # List manually installed packages

Holding packages is useful when you need to prevent a specific version from being upgraded — for example, keeping a specific kernel version or a software version that a custom application depends on.

Historical Context: Why apt-get Survived

Understanding why apt-get was not simply replaced by apt explains why both still exist.

When Debian introduced apt as the new user-friendly frontend, they faced a compatibility challenge: thousands of tutorials, scripts, Docker images, CI pipelines, and automation tools were written using apt-get. Changing or removing apt-get would break all of them.

The solution was to introduce apt as an additional tool for interactive use while keeping apt-get unchanged. The tools coexist: apt for humans at the terminal, apt-get for automation and scripts. Both are maintained and both receive updates. The intention was never for apt to replace apt-get — it was to provide a better experience for the common interactive case while keeping the scriptable, stable interface intact.

This dual-tool design is actually good engineering: the interface for human use can evolve (progress bars, colors, simplified commands) without breaking the stable machine-readable interface that automation depends on.

Quick Reference: Which Tool for Which Task?

Use Case Recommended Tool Reason
Interactive terminal: install packages apt Progress bar, color, user-friendly
Interactive terminal: search packages apt Single command, better output
Interactive terminal: upgrade system apt Clear output, helpful summary
Shell scripts apt-get Stable output, won’t break on version updates
Docker containers and CI apt-get Industry convention, automation context
Install build dependencies apt-get build-dep No apt equivalent
Download source packages apt-get source No apt equivalent
Query package dependencies apt-cache depends Detailed dependency info
Check repository version apt-cache policy Version and source info
Hold/unhold packages apt-mark hold/unhold Package state management
Fix broken packages apt install -f or dpkg --configure -a Repair package states

Conclusion: Two Tools with Clear Roles

The apt vs. apt-get question has a simple answer once you understand the design intent: apt for humans, apt-get for scripts. Both work correctly, both are maintained, and both will remain part of Debian and Ubuntu for the foreseeable future.

For everyday interactive use — sudo apt update && sudo apt upgrade, sudo apt install something, apt search term — apt is the modern, recommended choice with its progress bars and cleaner output. For scripts, Dockerfiles, CI pipelines, and anywhere that automation will parse command output or needs guaranteed output stability — apt-get is the right tool.

When you see apt-get in a tutorial, it is probably correct for that context (often automation-related) or simply reflects the author’s habit of using the older tool everywhere. When you see apt in a tutorial, it reflects modern best practice for interactive use. Neither is wrong — they are different tools for different contexts, and understanding that distinction makes you a more informed Linux user.

Hot this week

C++ Performance Profiling and Optimization Techniques

Master C++ performance optimization. Learn how to profile code, eliminate bottlenecks, leverage CPU caches, use Google Benchmark, and apply modern C++ techniques for maximum speed.

Implementing Design Patterns in Modern C++: A Complete Guide

Discover how modern C++ (C++11/14/17/20) revolutionizes classic GoF design patterns. Learn to write safer, cleaner, and more efficient code using smart pointers, lambdas, concepts, and std::variant.

SIMD Programming in C++: A Comprehensive Guide to Vectorization

SIMD (Single Instruction, Multiple Data) programming in C++ is...

Writing Cache-Friendly C++ Code

Learn to write cache-friendly C++ code — understand CPU caches, cache lines, spatial and temporal locality, data-oriented design, struct layout, false sharing, and how to measure cache performance.

Understanding Undefined Behavior in C++

Master C++ undefined behavior — learn what it is, the most dangerous forms (signed overflow, null dereference, data races, UB in templates), how compilers exploit it, and how to detect and eliminate it.

Topics

C++ Performance Profiling and Optimization Techniques

Master C++ performance optimization. Learn how to profile code, eliminate bottlenecks, leverage CPU caches, use Google Benchmark, and apply modern C++ techniques for maximum speed.

Implementing Design Patterns in Modern C++: A Complete Guide

Discover how modern C++ (C++11/14/17/20) revolutionizes classic GoF design patterns. Learn to write safer, cleaner, and more efficient code using smart pointers, lambdas, concepts, and std::variant.

SIMD Programming in C++: A Comprehensive Guide to Vectorization

SIMD (Single Instruction, Multiple Data) programming in C++ is...

Writing Cache-Friendly C++ Code

Learn to write cache-friendly C++ code — understand CPU caches, cache lines, spatial and temporal locality, data-oriented design, struct layout, false sharing, and how to measure cache performance.

Understanding Undefined Behavior in C++

Master C++ undefined behavior — learn what it is, the most dangerous forms (signed overflow, null dereference, data races, UB in templates), how compilers exploit it, and how to detect and eliminate it.

CMake Mastery: Modern C++ Build Systems

Master CMake for modern C++ projects — learn targets, properties, find_package, FetchContent, generator expressions, testing with CTest, and professional project structure.

Building Cross-Platform C++ Applications

Learn to build cross-platform C++ applications — handle OS differences, use CMake, manage compiler quirks, abstract platform APIs, write portable code, and test on multiple targets.

Coroutines in C++20: Asynchronous Programming

Master C++20 coroutines — learn co_await, co_yield, co_return, promise types, awaitables, generators, and how to build async tasks and lazy sequences without callback hell.

Related Articles

Popular Categories