First anniversary was coming up and I wanted a real photobook, not a shared album link. The online builders are fine. I just didn’t want their templates deciding how our year looked.
So I built a layout app for myself using Cursor.
The actual work for me was photos. Picking them, cutting the weak ones, choosing the cover and the last page, writing down what layouts were even allowed. Portrait rows of two or three. Landscapes on their own. No lone portrait floating on a landscape page. Cream letterbox when cropping would cut faces. Photobooth strip across two facing pages so you can see the whole thing without flipping.
Cursor Grok 4.5 did the layout execution from there. Lots of models can spit out Python. I needed one that would stick to the rules after I’d written them, and move fast enough that I’d stay in the loop. Flip a spread, scribble a note, ask for a tweak, get a new export.
What we built was a local preview that looks like an open album. Left and right spreads, notes on the side per page, and a “Save for agent” button that dumps feedback into JSON for the next pass.

I also wanted the date on each photo, small, at the bottom. Told the agent once and done nicely.
I spent most of the time curating photos and vetoing layouts I didn’t like. The agent packed pages and rendered them. Book’s ordered right in time for my anniversary.
What I’d do again
Set constraints so the agent can perform inside them. Don’t ask it to invent the whole design. Decide the rules first (allowed layouts, banned ones, cream over crop). Once the box is clear, packing and rendering get a lot more reliable.
Make the feedback loop easy for you and easy for the agent. I could flip spreads and leave page notes in one place. The agent got structured JSON it could read on the next pass. If giving feedback is annoying, or the agent can’t understand it cleanly, you are not iterating effectively.