DockProgress for macOS Dock Icon Progress Indicators
Show progress in your app's Dock icon
At a glance
- What is it?
- DockProgress is a Swift package for displaying progress or status directly in a macOS app's Dock icon. It supports Foundation Progress values, SwiftUI bindings, built-in indicators, and custom drawing for macOS 12 and later.
- Who is it for?
- DockProgress is appropriate for a macOS app that needs a visible completion indicator after the user leaves its window. It is unsuitable for Windows, iOS, or applications that only require an in-window progress display.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
DockProgress for Visible macOS Background Work
DockProgress addresses a specific macOS interface problem: showing that an application is still working after its user moves to another application. Instead of placing progress inside the app's window, the package renders it over or around the app's Dock icon. This can suit imports, synchronization, uploads, downloads, batch processing, and other tasks with a progress value that the application already knows.
The package is written in Swift and supports macOS 12 or later. It is aimed at developers of native macOS applications using SwiftUI or Foundation. It does not create the background operation, calculate progress, or provide a complete progress dialog. The application must own that work and pass values to DockProgress.
Two integration models are documented. One assigns a numeric progress value directly. Another connects DockProgress to a Foundation Progress object. SwiftUI applications can also use a view modifier that takes the same kind of value used by an ordinary ProgressView.
This narrow design keeps the package focused on a surface that standard in-app progress views do not cover. It also means DockProgress should complement, rather than automatically replace, progress details such as labels, cancellation controls, error messages, and estimated completion time. The README does not document menus, notifications, historical summaries, or progress persistence between application launches.
DockProgress API and Progress Data Flow
The basic API exposes DockProgress through a shared progress property. An application can copy the latest value from an existing update callback. The README places this statement inside a function and requires execution on the main actor:
foo.onUpdate = { progress in
DockProgress.progress = progress
}Here, `foo` represents the application's own progress source. When its value changes, the callback sends that value to DockProgress, which updates the app's Dock representation. DockProgress does not need to own the operation. The application remains responsible for the range and meaning of the value, as the README does not document validation or out-of-range behavior for direct assignments.
The package can also observe a Foundation Progress instance:
import Foundation
import DockProgress
let progress = Progress(totalUnitCount: 1)
progress.becomeCurrent(withPendingUnitCount: 1)
DockProgress.progressInstance = progressDockProgress stores that instance weakly. The application must retain it elsewhere for as long as it is needed. Assigning the instance alone does not transfer ownership. This is the clearest integration requirement in the API documentation.
SwiftUI applications can bind a state value to DockProgress:
struct ContentView: View {
@State private var progress = 0.0
var body: some View {
VStack {
ProgressView(value: progress)
Button("Start") {
progress = 0.5
}
}
.dockProgress(progress)
}
}The same value drives the in-window ProgressView and the Dock indicator. Passing nil resets DockProgress. By default, the modifier also resets progress when the SwiftUI view disappears.
Adding DockProgress Through Xcode
DockProgress is distributed as a Swift package and installed through Xcode. The README directs developers to add this URL in the Swift Package Manager tab:
https://github.com/sindresorhus/DockProgressThe documented version is 5.1.0, and the application must target macOS 12 or later. Xcode handles dependency resolution after the package reference is added; the README does not document a separate command-line installation or a manual source-copy procedure.
For a first SwiftUI implementation, import DockProgress, bind a Double to @State, and attach `.dockProgress(progress)` to the view associated with the operation. Configure one style during application launch. The following example selects the squircle representation:
import SwiftUI
import DockProgress
@main
struct MyApp: App {
init() {
DockProgress.style = .squircle(color: .white.opacity(0.5))
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}With the earlier SwiftUI example, pressing Start changes the state value to 0.5. The Dock indicator should then reflect that value. This is a documentation-based integration example, not a claim that DockProgress was executed during review.
The style should be set once at launch. The README does not explain what happens if multiple style assignments occur later. Teams should treat the launch configuration as the package's documented model and place it with the rest of the app's startup state.
DockProgress Bar, Squircle, Circle, Badge, and Pie Styles
The default DockProgress style is a bar:
DockProgress.style = .barA bar suits bounded progress because its extent can communicate an unfinished operation. The squircle style is intended to fit around a macOS app icon:
DockProgress.style = .squircle(color: .white.opacity(0.5))The README says the squircle fits the icon by default and that its inset parameter can adjust the placement. This makes it a candidate when the progress layer must follow the icon's rounded geometry rather than sit inside a conventional rectangular frame.
The circle style accepts a radius and color:
DockProgress.style = .circle(radius: 55, color: .blue)The pie style uses another filled-progress representation:
DockProgress.style = .pie(color: .blue)Badge mode represents a count rather than a percentage:
DockProgress.style = .badge(color: .blue, badgeValue: { getDownloadCount() })The closure lets the application provide a current value, such as a download or file count. According to the README, large values are shortened: 1012 becomes 1k and 10000 becomes 9k+. The documentation explicitly limits `badgeValue` to counts, so using it for completion percentages would conflict with its intended semantics.
Style selection should follow the value's meaning. A bounded operation fits bar, circle, pie, or squircle. A discrete quantity fits badge mode. The README does not document automatic selection, multiple simultaneous indicators, or separate styles per active application window.
Custom DockProgress Views and Canvas Rendering
DockProgress permits custom indicators through three documented extension points. A SwiftUI View style accepts a progress value and can return any SwiftUI view. A Canvas style receives `context`, `size`, and `progress`, allowing the application to draw directly. A legacy Core Graphics style accepts a draw handler with a `CGRect`.
A custom view is the most expressive option within the documented API because it can use normal SwiftUI composition. The Canvas route avoids building a view hierarchy and gives the drawing closure direct graphics primitives, although the README does not provide performance measurements or detailed guidance about when to select it. The Core Graphics form is identified as a backward-compatibility path.
The repository contains an Example directory with an Xcode project. The README points developers there for demonstrations of the built-in and custom styles. That example project is more useful than inventing a custom implementation from the abbreviated API descriptions, especially because custom code must account for Dock icon geometry and the visible size of the drawing area.
Custom styling also shifts work to the adopter. The application becomes responsible for drawing clarity, color contrast, and whether the indicator remains understandable at icon scale. DockProgress does not document automatic accessibility annotations, localization behavior for badge values, or per-user icon appearance adjustments. A custom style can therefore provide flexibility, but it can also introduce presentation defects that the package cannot diagnose without application-specific tests.
DockProgress Ownership Boundaries and macOS Alternatives
DockProgress has a narrow platform boundary. It requires macOS 12 or later and updates the macOS Dock icon. It is not a documented solution for Windows, Linux, iOS, or browser-based applications. An application targeting those platforms needs a progress surface appropriate to its own operating system and user interface framework.
The weak reference assigned through `DockProgress.progressInstance` is the main lifetime hazard. A Foundation Progress object can disappear if the application fails to retain it. The README does not document cancellation, retry, persistence after relaunch, or restoration after the Dock icon changes state. It also does not describe multiple concurrent operations or how their values should be combined.
The SwiftUI modifier's automatic reset on view disappearance may also conflict with work that outlives its originating interface. Developers need to verify that the view's lifetime matches the operation. If not, they can pass nil when appropriate, but the README does not prescribe an application-level coordinator for background work.
An in-window ProgressView is the clearest alternative for interactive work. It can sit beside controls and explanatory text without changing focus. DockProgress's difference is location and visibility from other applications. A custom SwiftUI overlay is another option when progress requires a larger or more detailed interface. DockProgress is the appropriate choice only when a compact indicator on the Dock communicates useful state better than an interface tied to the app's window.
DockProgress Releases, License, and Upgrade Checks
The repository is not archived. Its last push was on 2026-10-10. The README lists version 5.1.0 as the latest version, released on 2026-01-25. It also lists 5.0.2 from 2025-11-27 and 5.0.1 from 2025-11-10.
The package uses the MIT license. The repository includes a `license` file, `Package.swift`, source and test directories, and an Example Xcode project. That layout lets adopters inspect package metadata and examples before adding the dependency. It does not replace their own review of the exact license text or application distribution requirements.
Upgrade cost appears modest at first because the documented surface consists of a progress property, a Progress instance property, a SwiftUI modifier, styles, and custom drawing APIs. However, the README does not provide a version-by-version migration guide. Applications should compare their existing style and integration code against the API for the target package release.
The clearest checks before upgrading are the macOS 12 minimum, correct ownership of any Foundation Progress object, the chosen app-level location for style assignment, and continued support for both SwiftUI and non-SwiftUI call sites. The repository's release history shows recent package updates, but it does not document downstream application compatibility beyond the README's stated platform requirement.
Editorial conclusion
DockProgress is appropriate for a macOS app that needs a visible completion indicator after the user leaves its window. It is unsuitable for Windows, iOS, or applications that only require an in-window progress display. Before adoption, verify the package target, macOS 12 deployment requirement, ownership of any Progress instance, and whether the selected style remains legible against the app's Dock icon.
Frequently asked questions
How do I install DockProgress in a macOS app?
Add `https://github.com/sindresorhus/DockProgress` through the Swift Package Manager tab in Xcode. DockProgress requires macOS 12 or later, and the README lists version 5.1.0 as the latest version.
How do I show SwiftUI progress in the Dock with DockProgress?
Keep the progress value in SwiftUI state and apply `.dockProgress(progress)` to the relevant view. Pass nil to reset it, and note that progress resets by default when the view disappears.
Why must I retain a Progress instance passed to DockProgress?
DockProgress stores the assigned Progress instance weakly. The application must retain the instance for as long as it is needed.
Which DockProgress styles are available?
The README lists bar, squircle, circle, badge, and pie styles. It also documents custom SwiftUI View, Canvas, and legacy Core Graphics drawing paths.
Can DockProgress badge mode display a percentage?
The README says `badgeValue` is intended for counts such as downloads or files, not percentages. Use a progress-oriented style for a bounded completion value.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sindresorhus-dockprogress)Was this useful?