Here is the Swift source and build instructions for a command line tool to produce the following type of output: The source is best suited for opening in a proper programmer’s editor, and the only dependency is that one needs the current command-line tools for Xcode, or Xcode itself installed.
This was tested with command line tools for Xcode 26.4 (Swift 6.3) on macOS Tahoe 26.4.1. Your mileage may vary if you use older tools. It will use NSOpenPanel when no folder argument is provided on the command line.

#!/usr/bin/env swift
// Compile: xcrun --sdk macosx swiftc -Osize -o extSumx extSumx.swift
// Tested: 2026-04-18, Swift v6.3, macOS Tahoe 26.4.1
// Usage: extSumx
// extSumx ~/Downloads
import Foundation
import AppKit
func formatBytes(nbr: Int64) -> String {
// automatically uses appropriate SI storage abbreviation for locale
let autoLocale = Locale.autoupdatingCurrent.identifier
let style = ByteCountFormatStyle(style: .file,
allowedUnits: [.all],
spellsOutZero: true,
includesActualByteCount: false,
locale: Locale(identifier: autoLocale))
return style.format(nbr)
}
func fileChooser() -> String {
let openPanel = NSOpenPanel()
openPanel.isFloatingPanel = true
openPanel.setFrame(CGRect(x: 0, y: 0, width: 600, height: 525), display: true)
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = false
openPanel.allowedContentTypes = [.folder]
guard openPanel.runModal() == .OK else {
exit(1)
}
return openPanel.url!.path
}
var urlFolder: URL
let inputArgs: [URL]
var extDict: [String: Int64] = [:]
let headingOne = "Extension"
let headingSpaces = String(repeating: " ", count: 15)
let headingTwo = "Size"
var mutString = NSMutableString(format: "%-16@%@%12@\n",
headingOne, headingSpaces, headingTwo)
inputArgs = CommandLine.arguments.dropFirst().map { URL(fileURLWithPath: $0).standardizedFileURL }
if inputArgs.isEmpty {
urlFolder = NSURL(fileURLWithPath: fileChooser() ) as URL
} else {
urlFolder = inputArgs[0]
}
let fm = FileManager.default
let propKeys: [URLResourceKey] = [.fileSizeKey]
let enumOptions: FileManager.DirectoryEnumerationOptions = [.skipsHiddenFiles,
.skipsPackageDescendants]
// perform a recursive dive into specified directory
let enumerator = fm.enumerator(at: urlFolder, includingPropertiesForKeys: propKeys,
options: enumOptions,
errorHandler: nil)
let filePaths = enumerator?.allObjects as? [URL]
for afile in filePaths! {
let anExt = afile.pathExtension.localizedLowercase
guard !anExt.isEmpty else {
continue
}
let attributes = try fm.attributesOfItem(atPath: afile.path)
let fileSize = (attributes[FileAttributeKey.size] as? NSNumber)!.int64Value
// dynamically add a new extension, or update value for extension if multiples found
if extDict[anExt] != nil {
// add the new same extension file size to existing value
let itsValue = fileSize + extDict[anExt]!
extDict.updateValue(itsValue, forKey: anExt)
} else {
extDict[anExt] = fileSize
}
}
// Descending sort on size
let extDictSorted = extDict.sorted(by: { $0.value > $1.value })
for (k, v) in extDictSorted {
guard !k.isEmpty else {
continue
}
mutString.appendFormat("%-16s %12s\n", (k as NSString).utf8String!,
(formatBytes(nbr: v) as NSString).utf8String!)
}
print(mutString)
exit(0)