Should I vibe code
Portfolio websites, galleries, ecommerce, proofing, and client delivery
The client's forty-three chosen frames are the invoice. That list lives in a table you refactored on a Sunday.
?
Their verdict, the Professional price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.
?
Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.
The honest answer
why the verdict is what it is
The word doing the damage in that tagline is proofing. A portfolio is a weekend and the Carbonmade entry already covers why the resize pipeline is its hard part. A store is a hosted checkout and an email. Proofing is neither: it is a record of a decision a paying client made, and it is the document you deliver against and bill against. When the couple picks forty-three frames for the album, that list is not a UI state, it is the agreement. Build it as a boolean on an image row and it survives exactly until the first re-import, the first reorder, the first time you decide filenames make better identifiers than opaque IDs. And unlike the Pixieset failure, which is a leak, this one is silent — nobody sees a wrong list, they see an album, and the argument happens weeks later with no evidence on either side. Stack a real store with customer accounts and shipping addresses on top, put all of it behind one admin session on the same domain as a public site engineered to be crawled, and the coupling does the rest.
What actually breaks
not "if". the specific failures.
- The selection record, the first time image identifiers are regenerated on re-import and forty-three chosen frames silently become forty-three different photographs
- Selections stored as a mutable flag, which means there is no history, no timestamp, and nothing to show a client who remembers choosing something else
- Three authentication systems sharing one session cookie — admin, client gallery, store customer — where a flaw in the least important one reaches the most important one
- The gate on private galleries, when images are served from a storage path derived from the gallery name and the password only ever protected the HTML
- The store, on its second order: a payment webhook retried without an idempotency key either charges twice or ships nothing, and the customer's only record is an email
- Shipping addresses and customer accounts, which arrive with the store and turn a photography site into a system holding other people's home addresses
- SEO across a redesign, because a portfolio exists to be found and a rebuild that changes every URL without a redirect map deletes years of ranking in one deploy
- The domain, twelve months in, when the first-year registration you got as part of a bundle renews on a card that has since expired
- The contact form, which is the actual product, and which fails by accepting the message, showing the thank-you page and delivering nothing
The refactor was reasonable. Galleries had grown a mess of duplicate uploads, so you wrote a re-import that de-duplicated by file hash and rebuilt the image table cleanly. It ran on a Sunday evening and it worked — the galleries looked better afterwards, and the client-facing pages were faster. What you did not think about is that selections were stored as a row pointing at an image id, and the re-import issued new ids. The rows survived. They now point at whatever ended up in those positions. Three weeks later an album arrives at a wedding client's house containing eleven photographs she is certain she did not choose and missing the one of her grandmother, who has since died. She is not angry about the layout. She wants to know how you decided, and the honest answer is that your database decided, at 8pm on a Sunday, with no log, no timestamps and no export of what the original forty-three were. There is no backup that helps, because the backup contains the same rows.
Is that you?
the verdict is a default, not a law
- It is your portfolio and a contact form, with client delivery handled by something you pay for
- Selections are an append-only log with timestamps, exported to a file the moment a client marks a set final
- Image identifiers are assigned once at ingest and are never derived from filename, order or position
- The store is a hosted checkout, orders arrive as email, and your code never sees a card number
- Proofing decisions are a boolean you can flip and cannot reconstruct
- The public site and the private galleries share a bucket, a CDN path or a sitemap
- One session cookie authenticates the admin, the gallery client and the store customer
- You are holding shipping addresses and customer accounts with no plan for deletion requests
- You are hosting other photographers' sites, which makes you a hosting company with nobody on call
If you build it anyway
the checklist, then the prompt that enforces it
- Make selections append-only events — gallery, image, client, timestamp, action — never a mutable flag. The list is a commercial record, and records have history.
- Assign each image a permanent identifier at ingest, decoupled from filename, hash and position, and treat reissuing identifiers as a destructive operation requiring an export first.
- Export the selection list to a plain file and email it to both parties the moment a client marks a set as final. That file is what you deliver against when memories differ.
- Keep public and private on separate buckets with separate hostnames, and serve every private byte — thumbnails included — through short-lived signed URLs. Verify from an unauthenticated machine that direct access returns 403.
- Give the admin, the gallery client and the store customer separate sessions with separate cookies and separate scopes. One cookie for three roles is the coupling that turns a small bug into a large one.
- Use a hosted checkout, and make the payment webhook idempotent with a keyed order state machine. Double charges and silent non-fulfilment are the same missing line of code.
- Ship a redirect map with every redesign. A portfolio's traffic is search traffic, and changing every URL in one deploy is the most common self-inflicted wound on this list.
- Monitor the contact form and order notifications end to end — submit from outside your network on a schedule and alert when nothing arrives.
- Strip GPS from EXIF on downloadable files, keep the copyright and creator fields, and preserve ICC profiles through every resize.
I am building a portfolio site that also runs client galleries with proofing
and a store. The website is the easy part and the least important. Build the
records a client could dispute before anything that looks nice.
1. Start with the selection record. A client choosing an image appends an
immutable event — gallery, image, client, timestamp — rather than toggling
a flag. That log is what I invoice and deliver against.
2. Give every image a permanent identifier at ingest, never derived from
filename, hash, order or position. If I later ask for a re-import, refuse to
reissue identifiers and tell me what that does to every past selection.
3. Export selections as a plain file automatically when a client marks a set
final, and send it to both of us.
4. Then access: public site and private galleries in two separate buckets on
two hostnames. Not two folders. Explain why a prefix is not a boundary.
5. Serve every private byte, previews and thumbnails included, via short-lived
signed URLs issued after the gate passes, and prove an anonymous direct
request returns 403.
6. Gallery URLs are long random tokens, revocable in one action. Never a client
name, never a sequential number.
7. Then the store, on a hosted checkout. Write no code that can see a card
number and no table that could hold one.
8. Orders are append-only with a state machine, and the payment webhook is
idempotent. Charging twice and shipping nothing are the same bug.
9. Give admin, gallery client and store customer separate sessions and scopes.
10. Submit the contact form from outside my network on a schedule and alert me
when the message does not arrive.
11. Every redesign ships a redirect map. This site's job is to be found.
12. Out of scope unless I ask: inventory, customer accounts, invoicing, tax.
Finish by telling me what Pixpa costs.That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.
their build prompt ↗Or don’t build it
the boring option, and the way back out
The moment a client's choices become a deliverable. Twenty dollars a month buys galleries, proofing and a store that thousands of photographers have already broken in every way you are about to, and — more usefully — it buys separation you would otherwise have to design between a site built to be crawled and files that must never be. Build your own portfolio; it is a good weekend and the result will look more like you. Just do not let it grow proofing, a checkout and customer accounts on three consecutive Sundays, because that is precisely how this product gets rebuilt by accident.
$20/mo is cheaper than your weekend.
Split the exit in three, because the three halves of this product leave differently. The site is easy: static output, images in folders a human can read, redirects preserved. The store needs an order export with line items, addresses and payment references, kept where you keep tax records rather than where you keep code — and a hosted checkout means the payment history survives in your processor regardless. The galleries are the part people get wrong: export the selection log with timestamps, not just the images, because the images are recoverable from your own drives and the record of what was chosen is not. Last task on the way out is confirming every previously reachable private URL now returns 403, and that the old sitemap is gone from the index.
Self-hosted photo management with protected albums and share links, which is the client-gallery half already built by people who have made the access-control mistakes.
Open-source visual website builder for the portfolio half if you want a builder rather than a static generator.
Open-source web-builder framework to embed if the page editor is the part you do not want to write.
Questions
Format and Pixieset are also YOUR FUNERAL. What does this entry add?
A different failure. Format's is disclosure — commercial work under embargo leaking through your own sitemap. Pixieset's is the gate: a password that protects the page and not the JPEGs. Pixpa's is quieter and has no security story at all. The proofing selection is a commercial record stored as UI state, and when it goes wrong nobody gets breached, nobody gets a notification, and the first sign is a client holding an album that contains the wrong photographs.
Isn't proofing just a favourites list?
It looks like one and it functions as a contract. The selection determines what gets retouched, what goes in the album, what the client is charged for and what they receive. A favourites list can be wrong and nobody minds. A selection that is wrong is a dispute where each side is confident and neither has evidence — which is why it needs timestamps, immutability and an export, and why a boolean column is the wrong shape entirely.
Why does bundling a store make it worse rather than just bigger?
Because it introduces a second class of person who did not choose your code — a buyer — and a second class of data you now hold: addresses, order history, accounts. It also adds the one failure a photography site has no muscle for, which is a payment webhook retried in a way that either charges twice or fulfils nothing. Every one of those is fine on its own. Behind one admin login on one domain with one session cookie, they stop being independent.
- GDPR Art. 5 — principles relating to processing of personal data (EU)
- GDPR Art. 32 — security of processing (EU)
Every week, someone ships something they shouldn’t have.
New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.
Your portfolio is built to be crawled. The gallery beside it holds a campaign that has not launched yet.
The password gates the page. The JPEGs sit on a public bucket path, and Google does not need the password.
Nobody notices your layout. A photographer notices the second your resizer throws away the colour profile.
last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice