← All projects

A visual library · macOS & iOS App

Ambrel app icon

Ambrel

What catches your eye, kept close.

I built Ambrel for the references that get lost between screenshots, copied images and browser tabs. A shortcut saves them with their source. Your Mac reads their text, extracts their colours and finds similar images, so you can get back to what you saw even when you cannot remember where it was.

Real captures of Ambrel, with the same library of eighteen visual references throughout. Scroll to explore it, specimen by specimen. Further down, the new iPhone and iPad app and how the library syncs.

View project

01 Save

Keep it before you lose the thought.

Capture a region, save a copied image or keep a link. The quick-save panel lets you choose a board and tags without opening the library. Your usual macOS screenshots can be picked up from the menu bar too.

  • ⌃⇧4 Capture a region
  • ⌃⇧V Save the clipboard
02 Text

The year on the poster is enough.

Search for 1926: Ambrel finds the poster because it reads the text inside the image. Titles, sources and recognised subjects are searchable too, even if you never added a tag.

03 Colour

You remember the yellow.

Choose up to three colours, enter a hex value or use the eyedropper anywhere on screen. Ambrel puts the references where those colours stand out first, across boards and subjects.

04 Likeness

Start with one. Find its neighbours.

A reference can be the search itself. Ask for similar images and Ambrel compares it with the whole library. Follow the visual connection between references without having to name or tag what they share.

05 Inspect

The image keeps its context.

Open a capture to see its source, board, tags, recognised text and palette together. Copy the text, search by a colour or return to the original website without losing the reference.

06 Local

A library that stays on your Mac.

Text recognition, colour analysis and visual similarity all run on your Mac. The library is local and needs no account. iCloud sync is optional. Screenshots are stored as HEIC to keep the collection small.

Built around the Mac.

The small window is only the visible part. Capturing, understanding and retrieving a reference each use a different part of the system.

In the flow of other apps

SwiftUI and AppKit bring together the library, global shortcuts and the menu-bar quick-save panel. Saving a reference fits into the work already on screen.

Images become searchable

Apple’s Vision framework reads text, recognises subjects and produces the visual fingerprints used to compare images. The analysis happens on the device.

Files and an index

Images live in a local library, with SQLite keeping their metadata and image analysis. HEIC reduces the space taken by screenshots while their source stays attached.

New in 1.3

Your library, in your pocket too.

Ambrel 1.3 adds a free companion app for iPhone and iPad. It brings over the library you keep on your Mac through your own iCloud account: the inbox, the boards you choose and your saved searches. It saves images and links from any app’s Share button, and on iPad you can edit a board’s canvas.

It uses no system menus. Every action lives in floating glass bars that change with what you select, in a sheet of its own or in a bubble on the canvas, and a board opens by zooming out of the card you tapped. The aim was for it to feel as considered as the Mac app.

Ambrel on iPhone: the home screen of the Studio library, with its places and boards
iPhone · Home Inbox, all, favourites, links and the synced boards on one screen.
Ambrel on iPad: the Mediterranean Summer canvas board, with images, a title and notes
iPad · Canvas A canvas board as it was laid out on the Mac. On iPad it is editable: images, titles, text and notes.

Real screenshots from the iOS simulator, using the sample library that ships with the app so it can be tried without a Mac.

The hard part: syncing a library that already existed.

On the Mac, a library is a folder holding a SQLite database, the originals and the thumbnails, with indexes kept in memory. Taking it to iCloud could not mean rebuilding the app around another store, losing captures in a conflict or filling a phone with gigabytes of originals. These were the decisions.

  1. CKSyncEngine on top of the same SQLite

    No migration to Core Data or SwiftData: the store, the searches and the indexes stay as they were, and sync is a layer that reads and writes rows. Nor the library folder in iCloud Drive, which syncs file by file and corrupts a database in WAL mode. The data lives in the private CloudKit database of the user’s own account, with no server of mine in between.

  2. An outbox the database fills itself

    SQLite triggers record every row that changes and which groups of fields changed, so no write path, undo included, can forget to sync. The record is built when it is sent, from the row as it is at that moment, and changes from iCloud are applied with the triggers silenced so they do not bounce back.

  3. Conflicts field by field, deletions with a safety net

    If CloudKit rejects a save because the record changed elsewhere, the app takes the server’s version, reapplies only the fields this device changed and sends it again. A batch from another device that would delete more than 50 captures and a fifth of the library pauses sync, and the Mac asks first. Deleted files go to the Trash.

  4. Only what you choose, originals on demand

    Sync is switched on per library and no board syncs by default: you choose them on the Mac. Each library has two zones, one for metadata and thumbnails and another for originals. The Mac downloads both, while the iPhone asks for an original only when you open, share or export it, and keeps a small cache.

  5. A share extension that writes to CloudKit

    An iOS share extension gets about 120 MB of memory, too little to decode a large PNG. Images are copied to the shared container for the app to process later, but links go up to CloudKit from the extension itself, with their title, author and a single cover frame, never the video. Each link has its ID from the moment the sheet opens, so it is never saved twice.

  6. The Mac licence, mirrored with a signed token

    The iOS app is free and sells nothing. Each Mac publishes its signed licence token (Ed25519) to the iCloud account, and the iPhone verifies it with the same public keys: with a valid licence or trial it can save, and without one it is read-only, as on the Mac. Each library is tied to a single iCloud account.

What testing on real devices changed

  • CKSyncEngine only fetches changes when a push flags the database or the app comes to the foreground. Pushes do arrive, but not always promptly, so nothing assumes they will.
  • A scheduled send only covers the zones that had changes when it was scheduled. Anything queued in another zone in the meantime is now requested separately after each send, from a detached task, because awaiting the engine inside its own callback crashes the app.
  • On a slow network, the first upload of a real library (42 captures, about 25 MB) kept timing out. It now goes up in batches of at most 8 MB or 100 records, metadata first and originals after, and the Mac shows how many captures are left.