[{"data":1,"prerenderedAt":393},["ShallowReactive",2],{"writing-\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app":3,"writing-surround-\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app":388},{"id":4,"title":5,"body":6,"date":375,"description":376,"draft":377,"extension":378,"image":379,"meta":380,"navigation":381,"path":382,"pillar":383,"readingTime":384,"seo":385,"stem":386,"__hash__":387},"writing\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app.md","How I rebuilt The Tours app: stack and workflow",{"type":7,"value":8,"toc":358},"minimark",[9,13,18,86,89,93,96,99,115,119,122,135,139,142,165,168,171,182,185,189,192,203,208,211,215,218,222,229,233,236,239,243,246,296,299,303,306,309,312,316],[10,11,12],"p",{},"The Tours solves one problem: finding good motorcycle roads, wherever you happen to be. Routes\nget AI-generated context where context helps. Over the last eight months I rebuilt the whole\nthing — the app and the backend — and the point of this piece is the workflow, not the app.",[14,15,17],"h2",{"id":16},"the-stack","The stack",[19,20,21,34],"table",{},[22,23,24],"thead",{},[25,26,27,31],"tr",{},[28,29,30],"th",{},"Layer",[28,32,33],{},"Tool",[35,36,37,46,54,62,70,78],"tbody",{},[25,38,39,43],{},[40,41,42],"td",{"data-label":30},"Development",[40,44,45],{"data-label":33},"Cursor",[25,47,48,51],{},[40,49,50],{"data-label":30},"Backend",[40,52,53],{"data-label":33},"Strapi",[25,55,56,59],{},[40,57,58],{"data-label":30},"Mobile app",[40,60,61],{"data-label":33},"React Native",[25,63,64,67],{},[40,65,66],{"data-label":30},"UI development",[40,68,69],{"data-label":33},"Storybook",[25,71,72,75],{},[40,73,74],{"data-label":30},"Design",[40,76,77],{"data-label":33},"Figma",[25,79,80,83],{},[40,81,82],{"data-label":30},"AI support",[40,84,85],{"data-label":33},"Claude \u002F GPT",[10,87,88],{},"The individual picks matter less than how they connect. What made this work is that every feature\ntravels the same documented path, from first idea to shipped screen. Six steps.",[14,90,92],{"id":91},"step-1-design-and-design-tokens","Step 1: Design and design tokens",[10,94,95],{},"The Figma designs came before any app code, and the design tokens went into code at the same\ntime: colours, spacing, border radius, shadows, all as named values.",[10,97,98],{},"That pays off the moment Cursor works from a Figma screen in Plan mode. It reads the tokens\ndirectly instead of pulling hex values out of a design, so the implementation stays close to the\noriginal without me copying numbers by hand.",[100,101,102,103,102,111],"figure",{},"\n  ",[104,105],"img",{"src":106,"alt":107,"width":108,"height":109,"loading":110},"\u002Fimages\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app\u002Fdesign-tokens.png","The primary brand colour defined as a design token, with the 50 to 900 scale mapped onto baseColors.primary",524,504,"lazy",[112,113,114],"figcaption",{},"The primary colour as a design token — the value Cursor reads instead of a hex code from the design.",[14,116,118],{"id":117},"step-2-a-component-library-in-storybook","Step 2: A component library in Storybook",[10,120,121],{},"From the Figma screens I built isolated, documented component stories in Storybook, again in Plan\nmode. That library then became the reference for every feature after it — it is how Cursor knows\nwhich component already exists instead of inventing a fourth button.",[100,123,102,124,102,132],{},[104,125],{"src":126,"alt":127,"width":128,"height":129,"loading":110,"className":130},"\u002Fimages\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app\u002Fstorybook-component.png","Storybook running on a phone, showing the AtomAnimation story above the sidebar list of Atom components",320,697,[131],"img--framed",[112,133,134],{},"The AtomAnimation story in Storybook, next to the rest of the Atom layer.",[14,136,138],{"id":137},"step-3-generating-user-stories","Step 3: Generating user stories",[10,140,141],{},"I had the AI write the user stories from the Figma screens. Three things made the difference:",[143,144,145,153,159],"ul",{},[146,147,148,152],"li",{},[149,150,151],"strong",{},"Work through a whole epic at once."," Eight to ten stories in one pass, not one story at a time.",[146,154,155,158],{},[149,156,157],{},"Give it an explicit structure."," The same template every time.",[146,160,161,164],{},[149,162,163],{},"Make it ask first."," Have it ask clarifying questions before it generates anything, instead of\nguessing.",[10,166,167],{},"That last one is the big one. It typically came back with around 50 questions. Answering them up\nfront raised the quality of the stories noticeably.",[10,169,170],{},"The template:",[172,173,179],"pre",{"className":174,"code":176,"language":177,"meta":178},[175],"language-text","As a XXX I want XXX so that XXX\n\nAcceptance Criteria\nDescription \u002F Context\nDefinition of Done\nDependencies\nTechnical Notes\n","text","",[180,181,176],"code",{"__ignoreMap":178},[10,183,184],{},"I reviewed every generated story and added or cut acceptance criteria, but most of it was right on\nthe first pass. A lot of the requirements can be derived from the screen itself, so what I mostly\nadded were the requirements you cannot see in a design. Writing these stories by hand would have\ntaken noticeably longer.",[14,186,188],{"id":187},"step-4-development-in-cursor","Step 4: Development in Cursor",[10,190,191],{},"Per feature, Cursor got three inputs: the user story, the relevant Figma screen, and — for\nfeatures that are pure logic with no new UI — the Storybook file instead of the screen, so it was\nclear which components to use.",[100,193,102,194,102,200],{},[104,195],{"src":196,"alt":197,"width":198,"height":199,"loading":110},"\u002Fimages\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app\u002Fcursor-plan.png","A Cursor plan for the profile tour list: goal, bullet requirements, and a flow diagram from Profile through ProfileToursList to the tours endpoint",744,352,[112,201,202],{},"A Cursor plan before any code is written — goal, requirements, and the path through the components.",[204,205,207],"h3",{"id":206},"cursor-rules","Cursor rules",[10,209,210],{},"Rule files kept the guidelines consistent across features. That worked well for the app and much\nless well for the backend. Large rule files in the backend were actively counterproductive; the\nfix was keeping them deliberately minimal. My guess is that Strapi's own prescribed structure\npulled the model away from the actual task.",[204,212,214],{"id":213},"splitting-the-work","Splitting the work",[10,216,217],{},"Cursor did most of the work. I did the small styling corrections by hand. The code stayed visible\nthe whole time, which is what let me review and adjust as it went rather than after.",[14,219,221],{"id":220},"step-5-backend-and-the-seam-to-the-frontend","Step 5: Backend and the seam to the frontend",[10,223,224,225,228],{},"Whenever Strapi got a new endpoint, a ",[180,226,227],{},".md"," file documenting it was written at the same time. That\ndocumentation then went into the next plan alongside the user story and the Figma screen, so the\nshape of the endpoint was clear from the first line of frontend code instead of being discovered\nhalfway through.",[14,230,232],{"id":231},"step-6-testing","Step 6: Testing",[10,234,235],{},"Honestly: still mostly manual, and I want to automate more of it.",[10,237,238],{},"What exists today: visual regression tests through Storybook and Maestro, unit tests in the\nbackend with Jest, and a manual pass over every screen before each release.",[14,240,242],{"id":241},"what-changed","What changed",[10,244,245],{},"Eight months, 583 development hours for the build — design hours are separate.",[19,247,248,261],{},[22,249,250],{},[25,251,252,255,259],{},[28,253,254],{},"Metric",[28,256,258],{"align":257},"right","Frontend",[28,260,50],{"align":257},[35,262,263,274,285],{},[25,264,265,268,271],{},[40,266,267],{"data-label":254},"Commits",[40,269,270],{"align":257,"data-label":258},"611",[40,272,273],{"align":257,"data-label":50},"139",[25,275,276,279,282],{},[40,277,278],{"data-label":254},"Lines of code",[40,280,281],{"align":257,"data-label":258},"~378,000",[40,283,284],{"align":257,"data-label":50},"~221,900",[25,286,287,290,293],{},[40,288,289],{"data-label":254},"Merge requests (est.)",[40,291,292],{"align":257,"data-label":258},"~90",[40,294,295],{"align":257,"data-label":50},"~14",[10,297,298],{},"For the same scope, I would put this at roughly three to four times faster. But the time moved\nrather than disappeared: far more of it went into defining features and testing them, because\nproducing the code itself takes seconds to minutes. What took longest was defining the base\nstructure and the library cleanly, plus the genuinely interactive pieces like the mapping.",[14,300,302],{"id":301},"conclusion","Conclusion",[10,304,305],{},"I would do it this way again. You get to something usable fast.",[10,307,308],{},"The one habit worth stealing: when the AI goes off in the wrong direction, close the chat, stash\nthe changes, and start over with what you just learned. That beats trying to argue a stuck session\nback on track.",[10,310,311],{},"And the thing that actually decided the outcome was not the AI. It was the structure around it —\ndesign tokens, a clean component library, structured user stories, and a foundation of rules.",[14,313,315],{"id":314},"tools","Tools",[143,317,318,326,333,339,345,351],{},[146,319,320],{},[321,322,61],"a",{"href":323,"rel":324},"https:\u002F\u002Freactnative.dev",[325],"nofollow",[146,327,328],{},[321,329,332],{"href":330,"rel":331},"https:\u002F\u002Fgithub.com\u002Fstorybookjs\u002Freact-native",[325],"React Native Storybook",[146,334,335],{},[321,336,53],{"href":337,"rel":338},"https:\u002F\u002Fstrapi.io",[325],[146,340,341],{},[321,342,45],{"href":343,"rel":344},"https:\u002F\u002Fcursor.com",[325],[146,346,347],{},[321,348,77],{"href":349,"rel":350},"https:\u002F\u002Ffigma.com",[325],[146,352,353],{},[321,354,357],{"href":355,"rel":356},"https:\u002F\u002Fclaude.ai",[325],"Claude",{"title":178,"searchDepth":359,"depth":359,"links":360},3,[361,363,364,365,366,370,371,372,373,374],{"id":16,"depth":362,"text":17},2,{"id":91,"depth":362,"text":92},{"id":117,"depth":362,"text":118},{"id":137,"depth":362,"text":138},{"id":187,"depth":362,"text":188,"children":367},[368,369],{"id":206,"depth":359,"text":207},{"id":213,"depth":359,"text":214},{"id":220,"depth":362,"text":221},{"id":231,"depth":362,"text":232},{"id":241,"depth":362,"text":242},{"id":301,"depth":362,"text":302},{"id":314,"depth":362,"text":315},"2026-06-20","I rebuilt The Tours from scratch in eight months and 583 hours — app and backend. Figma, Storybook, Cursor and structured user stories, including the parts that did not work.",false,"md",null,{},true,"\u002Fwriting\u002Fhow-i-rebuilt-the-tours-app","BUILDING WITH AI",5,{"title":5,"description":376},"writing\u002Fhow-i-rebuilt-the-tours-app","FEDOpemEtcJcxF3hMiCDZqLJWWugSvS6WigKSoNexyE",[379,389],{"title":390,"path":391,"stem":392,"children":-1},"Jev: first steps","\u002Fwriting\u002Fjev-first-steps","writing\u002Fjev-first-steps",1792666226085]