This is a submission for the Sanity Challenge, Path Two: Vibe-Code Something Strange
What I Built
Think of one thing you own that's almost fine.
A shirt with a missing button. A tote with an open seam. A cushion that's starting to come apart at the edge.
The damage is small. The distance between "I should fix that" and actually fixing it can be surprisingly large. You still need to work out what happened, which tools you need, and whether this is a five-minute job or your entire afternoon.
I built Mend to make that first step smaller.
It's a repair room for adult clothing, fabric bags, and household textiles. Bring the time you have and the tools you own. Mend finds a suitable plan, shows what's missing, and gives you a checklist you can save and come back to.
A small library on purpose: six repairs with specific symptoms, limits, and credited sources.
There is no account to create. Your tools and repair progress stay in your browser. The shared repair library lives in Sanity.
I wanted the interface to feel like a place you'd enjoy spending a few minutes: warm paper, a green workbench, little lilac details. But the useful part is much less decorative: what can I repair with what I have, right now?
Demo
Open Mend and try the one-minute challenge
Code
Mend
A little repair goes a long way. Mend helps people repair adult clothing, fabric bags, and household textiles before replacing them.
What works
- Search six sourced repair plans and filter by category or time.
- Match repairs to available minutes and your existing tools; see what is missing.
- Save plans, check off steps, and resume after reloading the browser.
- Complete repairs and optionally record the measured item weight.
- View your repair journal, export it as JSON, or print an individual plan.
- Edit reusable tools and repair guides in Sanity Studio with a review process.
- Use the responsive interface on desktop and mobile, with keyboard-accessible dialogs and reduced-motion support.
The planner uses explicit content relationships and deterministic matching. It does not generate repair advice at runtime. The library contains original preparation checklists, each credited and linked to its full illustrated source. It is intentionally small; the seed library is a starting…
A tiny challenge for you
Imagine you have 15 minutes, a sewing needle, and scissors. Your category is Clothing.
Which repair should Mend suggest?
- A missing button
- An open seam with a 25-minute plan
- Everything in the library, because optimism
Reveal the match
The missing button. It fits the time limit, and you already have its required tools. The planner filters by category and duration first, then ranks the matches by missing tools. It still lists materials separately, so "you have the tools" doesn't mean you magically own a replacement button and thread.
Try that combination in Repair planner. Then change your available time or untick a tool and watch the match change.
The recommendation explains its requirements instead of hiding them behind a score.
Now choose Make this my plan, tick one step, close the checklist, and reload. Open My repair shelf: the checked step should still be there.
That little reload test matters to me. A repair plan should survive being interrupted by dinner, a phone call, or simply deciding to finish it tomorrow.
The checklist organizes the job. The credited illustrated guide supplies the detailed technique.
Finish the checklist and it joins your repair journal. You can optionally record the item's weight, print a plan, or export your journal as JSON.
What does "impact" actually mean here?
Mend counts completed repairs and totals the item weights you choose to enter. That's all.
I left carbon savings out. A checked box doesn't tell me how much CO2 was avoided, how long the repair lasted, or whether the item would otherwise have been thrown away. I'd rather show two understandable numbers than a very impressive number I can't defend.

Demo data: one test repair and a 250 g test weight. This demonstrates the journal; it is not measured environmental impact.
No test credentials are needed for the public app. Editing the library in Studio requires access to the Sanity project.
Code
The frontend is Astro + a React island + TypeScript. Sanity stores the repair library. Personal progress uses browser-local storage.
The build is static, so GitHub Pages can serve it. Content is read at build time, and the About view can refresh the latest public library. The repository includes a Pages build helper and a GitHub Actions workflow that calculates the repository's base path.
The schema became the product
A repair stores its exact symptom, duration, difficulty, materials, tool references, checklist steps, precautions, and credited source.
That specificity changes the behavior. A sticking zipper with intact teeth is a different problem from broken teeth. The first guide should not quietly become advice for the second.
Tools are separate documents. Several repairs reference the same needle, so its description can be maintained in one place. The planner uses those relationships to explain what a person is missing.
Show the GROQ behind the repair cards
This is the guide projection from the app's library query:
*[_type == "repairGuide" && review.status == "approved"]
| order(title asc) {
_id, title, summary, category, icon, color,
duration, difficulty, symptom, materials,
"tools": tools[]->{_id, name, description},
steps[]{_key, title, body},
caution, source, review{status, reviewedAt}
}
~~~
The client reads the published perspective. Drafts stay out of the public library.
Review the version you're about to publish
In Studio, an editor can Send for review → Approve repair → Publish.
Approval stores an exact snapshot of the reviewed fields. Change the content afterward and the Studio Publish action stays disabled until that version is reviewed again. A revision guard catches concurrent edits during approval.
This is a custom process built with documents and Studio actions. I didn't use the separate hosted Sanity Workflows product, App SDK, or Context MCP. The publishing guard helps editors coordinate; it isn't an API authorization boundary.
Three things testing caught
1. My IDs looked tidy. They were also private.
I seeded IDs like mend.guide.button. The authenticated import worked, but the public app couldn't read the records. Sanity documents that IDs containing dots are private. Hyphenated IDs fixed it. The public query now returns six guides and five tools, with no broken tool references.
2. The browser tests were faster than hydration.
The first test clicked the server-rendered interface before React was ready. I added a readiness marker and waited for it. The full journey now covers filtering, tool matching, saving, reloading, completing, and exporting.
3. Subtle text was too subtle.
Automated accessibility checks found low-contrast secondary text on some pastel surfaces. I darkened it, then checked the library, planner, dialog, impact view, and mobile view again.
The final local verification passes six unit tests and five browser/accessibility tests, including a run against the compiled /Sanity/ build. Automated checks are useful evidence, not a claim that every accessibility need has been evaluated.
The workbench image was generated with AI for this project and is disclosed in the app. It is decorative. Repair technique comes from the linked original sources.
Sanity Project Details
Project ID: 5zzpp9q6
Dataset: production
Inspect the public repair documents
The repository includes the schemas, Studio actions, library query, and seed importer. The checklists are independently written and linked to iFixit and Patagonia's guides on iFixit. Credits also appear beside each plan.
What would you put in the next six repairs? A button, a bag, a seam, or something I haven't thought of? Tell me the item and the damage in the comments. Specific problems would be much more useful than "support more repairs."
And if this gets one neglected shirt back into someone's regular rotation, that's a result I'd be happy to build on.




Top comments (0)