Make room, safely.
You decide what leaves.

Roomy finds similar photos, screenshots, large videos and duplicate contacts on your iPhone, and removes nothing until you review it. Everything runs on the phone.

View on GitHub iOS 17+ · SwiftUI · no account, no network
idle

Screens

Every screen as built, captured on iOS 27 with test photos and contacts. The same app in both appearances: it follows the iPhone, or a choice in Settings.

Light

Scroll sideways · 12 screens

Dark

Scroll sideways · 12 screens

Features

Storage at a glance

How full the phone is, what can be cleaned up, and one bottom button for the next step: scan, cancel, resume or review.

Similar photos

Exact copies across the library and near-identical shots from one moment, grouped with a Best pick and the reason they match.

Screenshots and large videos

Screenshots by month, videos by the space they take, with a player. Months fold, and a whole month selects in one tap.

Duplicate contacts

Cards that share a number or email are merged, never lost: every value is kept, and a backup is saved first.

One Review

Everything you pick lands in one list with sizes, then a single delete button, Roomy's confirmation and iOS's own.

Honest numbers

Photos kept only in iCloud stay out unless you include them. "Freed" appears only after free space is measured again.

How it works

01

Scan

Roomy reads the library on the phone and groups what can go. Nothing leaves it.

02

Review

Pick what goes. Nothing is picked for you, and the Best photo of each group is never selected.

03

Delete

Confirm in Roomy, then in iOS. Photos move to Recently Deleted; contacts are merged.

04

Empty Recently Deleted

In Photos. Only then is the space free, and Roomy shows the measured result.

Safety

One delete path

Only one part of the code can delete, and only from Review's confirmation. The build fails if a delete call appears anywhere else.

Removed is not freed

Deleted photos stay in Recently Deleted for 30 days. Roomy says so, links you there, and credits space only when it is measured.

On this iPhone by default

Deleting a photo kept only in iCloud frees nothing here but removes it everywhere, so those stay out unless you turn them on.

Backups before merges

Contacts have no undo, so every card is saved as a vCard first. Share it to Contacts to bring the originals back.

Tech stack

SwiftUI

Observable stores, Liquid Glass on iOS 26 and later, iOS 17 fallbacks

Swift 6

Strict concurrency; scanning runs off the main actor and streams progress

PhotoKit

One pass over the library; file sizes read only where they matter

Contacts

Region-aware phone matching, merge preview, vCard backups

dHash + LSH

64-bit perceptual hashes, 5 bands, union-find grouping, cached per photo

Figma first

Every screen, state and animation designed before it was built

XCTest

318 unit tests with fake photo and contact libraries

XcodeGen

Project generated from project.yml; no third-party packages

Architecture

Appcomposition
Featuresscreens
Storesstate
ServicesPhotos, Contacts
Corepure algorithms

Dependencies point one way, and a check script enforces it on every build, with file size, formatting and zero warnings.

Try it on your iPhone

Open Roomy.xcodeproj in Xcode, pick a simulator or your iPhone, and press Run. A free Apple ID is enough.

Get the code