[{"data":1,"prerenderedAt":552},["ShallowReactive",2],{"navigation":3,"/blog/10-coding-practices-i-follow-every-project":30,"/blog/10-coding-practices-i-follow-every-project-surround":549},[4],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Blog","/blog","blog",[9,13,17,21,25],{"title":10,"path":11,"stem":12},"10 Coding Practices I Follow on Every Project (So You Don’t Have To Regret Hiring Me)","/blog/10-coding-practices-i-follow-every-project","blog/10-coding-practices-i-follow-every-project",{"title":14,"path":15,"stem":16},"AI vs Human Developers in 2025: A Collaboration Playbook","/blog/ai-vs-human-developers-collaboration-playbook","blog/ai-vs-human-developers-collaboration-playbook",{"title":18,"path":19,"stem":20},"Frontend vs Backend: The Endless Battle for Supremacy (And Why You Shouldn't Care)","/blog/frontend-vs-backend-the-endless-battle-for-supremacy-and-why-you-shouldn-t-care","blog/frontend-vs-backend-the-endless-battle-for-supremacy-and-why-you-shouldn-t-care",{"title":22,"path":23,"stem":24},"Scaling New Heights: Building Scalable Vue and Nuxt Applications","/blog/scaling-new-heights-building-scalable-vue-and-nuxt-applications","blog/scaling-new-heights-building-scalable-vue-and-nuxt-applications",{"title":26,"path":27,"stem":28},"What Hiring Managers Really Look for in Developer Portfolios in 2025","/blog/what-hiring-managers-want-in-developer-portfolios-2025","blog/what-hiring-managers-want-in-developer-portfolios-2025",false,{"id":31,"title":10,"author":32,"body":38,"canonical":532,"coverAlt":533,"date":534,"description":535,"excerpt":536,"extension":537,"featured":29,"image":538,"meta":539,"minRead":540,"navigation":541,"path":11,"seo":542,"stem":12,"tags":543,"__hash__":548},"blog/blog/10-coding-practices-i-follow-every-project.md",{"name":33,"username":34,"to":35,"avatar":36},"Kadiri Success","codebyquan","https://twitter.com/codebyquan",{"src":37,"alt":33},"/avatar/kadiri.jpg",{"type":39,"value":40,"toc":516},"minimark",[41,46,65,68,72,76,87,90,98,101,103,107,110,118,121,126,129,140,143,145,149,157,177,180,191,194,196,200,203,214,217,241,244,255,257,261,264,275,278,286,289,297,304,306,310,313,316,324,327,335,338,340,344,347,355,358,369,372,383,386,388,392,395,398,409,412,417,420,422,426,429,440,443,446,457,459,463,466,469,480,482,490,493,495,499,502,513],[42,43,45],"h2",{"id":44},"tldr","TL;DR",[47,48,49,53,56,59,62],"ul",{},[50,51,52],"li",{},"These 10 habits are how I avoid “it works on my machine” drama.",[50,54,55],{},"I optimise for readability first, performance second (with measurements).",[50,57,58],{},"Git history must tell the story; no “final-final-v2” commits.",[50,60,61],{},"Tests, linting and basic monitoring are part of “done”, not an afterthought.",[50,63,64],{},"If a new teammate can’t ship in day one, the structure is wrong.",[66,67],"hr",{},[42,69,71],{"id":70},"_1-start-from-the-user-and-the-constraints","1. Start from the user and the constraints",[73,74,75],"p",{},"Before touching code, I write down three things:",[47,77,78,81,84],{},[50,79,80],{},"Who is this for?",[50,82,83],{},"What does “fast enough” mean in this context?",[50,85,86],{},"What constraints are we under? (time, budget, infra, team)",[73,88,89],{},"This gives me a simple decision filter:",[47,91,92,95],{},[50,93,94],{},"If a micro-optimisation doesn’t move user outcomes, I skip it.",[50,96,97],{},"If a feature makes onboarding harder with little gain, I push back.",[73,99,100],{},"Code is only “good” inside the context of the problem it solves.",[66,102],{},[42,104,106],{"id":105},"_2-favour-boring-predictable-architecture","2. Favour boring, predictable architecture",[73,108,109],{},"I’d rather have:",[47,111,112,115],{},[50,113,114],{},"A readable, slightly repetitive Nuxt page structure.",[50,116,117],{},"A simple service layer with clear boundaries.",[73,119,120],{},"than:",[47,122,123],{},[50,124,125],{},"A clever meta-framework nobody wants to touch in six months.",[73,127,128],{},"Patterns I use a lot:",[47,130,131,134,137],{},[50,132,133],{},"Clear separation of concerns: pages vs components vs composables.",[50,135,136],{},"Dedicated directories for API, content and utilities.",[50,138,139],{},"One “source of truth” for each piece of data (no copy-paste configs).",[73,141,142],{},"If a new dev can’t guess where a file lives, the structure needs work.",[66,144],{},[42,146,148],{"id":147},"_3-make-types-your-first-line-of-defence","3. Make types your first line of defence",[73,150,151,152,156],{},"I use TypeScript as a ",[153,154,155],"strong",{},"design tool",", not just a safety net:",[47,158,159,162,170],{},[50,160,161],{},"Define types for API responses and props early.",[50,163,164,165,169],{},"Model nullable cases explicitly instead of sprinkling ",[166,167,168],"code",{},"!"," everywhere.",[50,171,172,173,176],{},"Prefer ",[166,174,175],{},"zod"," or similar runtime validation at boundaries.",[73,178,179],{},"This reduces:",[47,181,182,185,188],{},[50,183,184],{},"“undefined is not a function” bugs.",[50,186,187],{},"Confusion about what a function expects or returns.",[50,189,190],{},"Surprises when backend contracts change.",[73,192,193],{},"Strong types are a free specification your future self will thank you for.",[66,195],{},[42,197,199],{"id":198},"_4-treat-git-history-as-documentation","4. Treat git history as documentation",[73,201,202],{},"My rules:",[47,204,205,208,211],{},[50,206,207],{},"One logical change per commit.",[50,209,210],{},"Commit messages describe intent, not implementation.",[50,212,213],{},"Branches are small and short-lived.",[73,215,216],{},"Examples:",[47,218,219,225,230,236],{},[50,220,221,222],{},"✅ ",[166,223,224],{},"feat: add RSVP guest limit with validation",[50,226,221,227],{},[166,228,229],{},"fix: debounce search to reduce API calls",[50,231,232,233],{},"❌ ",[166,234,235],{},"changes",[50,237,232,238],{},[166,239,240],{},"fix stuff",[73,242,243],{},"Good history lets you:",[47,245,246,249,252],{},[50,247,248],{},"Blame without drama.",[50,250,251],{},"Revert safely.",[50,253,254],{},"Onboard new people quickly.",[66,256],{},[42,258,260],{"id":259},"_5-write-tests-where-they-pay-off-the-most","5. Write tests where they pay off the most",[73,262,263],{},"I don’t test everything blindly. I test:",[47,265,266,269,272],{},[50,267,268],{},"Core business rules (money, access control, bookings).",[50,270,271],{},"Complex pure functions (formatters, calculators, mappers).",[50,273,274],{},"Critical flows (checkout, sign-up, contact).",[73,276,277],{},"I prefer:",[47,279,280,283],{},[50,281,282],{},"Fast unit tests for logic.",[50,284,285],{},"A few end-to-end tests to protect critical journeys.",[73,287,288],{},"And I always:",[47,290,291,294],{},[50,292,293],{},"Run tests before refactors.",[50,295,296],{},"Add tests when fixing bugs to avoid regressions.",[73,298,299,300,303],{},"The goal is ",[153,301,302],{},"confidence",", not 100 % coverage for its own sake.",[66,305],{},[42,307,309],{"id":308},"_6-let-automation-enforce-code-style-not-humans","6. Let automation enforce code style, not humans",[73,311,312],{},"Style debates waste human energy. Tools don’t argue.",[73,314,315],{},"I use:",[47,317,318,321],{},[50,319,320],{},"ESLint and formatters to enforce consistency.",[50,322,323],{},"Pre-commit hooks or CI checks to block broken code.",[73,325,326],{},"This means:",[47,328,329,332],{},[50,330,331],{},"Code reviews focus on architecture, UX and performance.",[50,333,334],{},"Developers don’t nitpick each other’s spacing or commas.",[73,336,337],{},"Once the rules are agreed, the tools do the enforcement.",[66,339],{},[42,341,343],{"id":342},"_7-measure-performance-instead-of-guessing","7. Measure performance instead of guessing",[73,345,346],{},"Instead of “this feels fast enough”, I:",[47,348,349,352],{},[50,350,351],{},"Use Lighthouse and WebPageTest for frontends.",[50,353,354],{},"Use logs and tracing for backend endpoints.",[73,356,357],{},"On portfolios and landing pages, I care most about:",[47,359,360,363,366],{},[50,361,362],{},"First Contentful Paint.",[50,364,365],{},"Largest Contentful Paint.",[50,367,368],{},"Interaction to Next Paint.",[73,370,371],{},"I optimise:",[47,373,374,377,380],{},[50,375,376],{},"Images first.",[50,378,379],{},"JavaScript bundle size second.",[50,381,382],{},"Third-party scripts last.",[73,384,385],{},"Performance is a feature, not a nice-to-have.",[66,387],{},[42,389,391],{"id":390},"_8-design-for-debugging-from-day-one","8. Design for debugging from day one",[73,393,394],{},"I ask: “When this breaks in production, how will we know why?”",[73,396,397],{},"So I:",[47,399,400,403,406],{},[50,401,402],{},"Attach identifiers to important requests and logs.",[50,404,405],{},"Use structured logging, not random console output.",[50,407,408],{},"Keep error messages helpful but not sensitive.",[73,410,411],{},"This turns “it’s broken” into:",[47,413,414],{},[50,415,416],{},"“This endpoint is returning a 500 for group X with payload Y.”",[73,418,419],{},"It saves hours of guesswork when things inevitably go wrong.",[66,421],{},[42,423,425],{"id":424},"_9-leave-the-campsite-cleaner-than-you-found-it","9. Leave the campsite cleaner than you found it",[73,427,428],{},"When I touch old code, I try to:",[47,430,431,434,437],{},[50,432,433],{},"Extract one messy block into a small function.",[50,435,436],{},"Rename one confusing variable to something clearer.",[50,438,439],{},"Add one missing test for a known edge case.",[73,441,442],{},"I don’t rewrite everything. I just improve the area I already have open.",[73,444,445],{},"Over time, this:",[47,447,448,451,454],{},[50,449,450],{},"Reduces complexity.",[50,452,453],{},"Improves morale.",[50,455,456],{},"Makes “legacy” code less scary.",[66,458],{},[42,460,462],{"id":461},"_10-communicate-clearly-early-and-often","10. Communicate clearly, early and often",[73,464,465],{},"The best code can still fail a project if communication is poor.",[73,467,468],{},"My habits:",[47,470,471,474,477],{},[50,472,473],{},"Share small updates instead of going silent for days.",[50,475,476],{},"Raise risks as soon as I see them, not after a deadline slips.",[50,478,479],{},"Translate technical trade-offs into business language.",[73,481,216],{},[47,483,484,487],{},[50,485,486],{},"“We can hit the deadline if we skip feature X and add it later.”",[50,488,489],{},"“This API choice saves us money but adds 80 ms latency—worth it?”",[73,491,492],{},"Good developers ship code; great developers build trust.",[66,494],{},[42,496,498],{"id":497},"final-thoughts","Final thoughts",[73,500,501],{},"These 10 practices are simple, but they compound:",[47,503,504,507,510],{},[50,505,506],{},"Fewer bugs.",[50,508,509],{},"Faster onboarding.",[50,511,512],{},"Happier users.",[73,514,515],{},"If you’re reading this as a potential client or teammate, this is the standard I bring to every project on this portfolio.",{"title":517,"searchDepth":518,"depth":518,"links":519},"",2,[520,521,522,523,524,525,526,527,528,529,530,531],{"id":44,"depth":518,"text":45},{"id":70,"depth":518,"text":71},{"id":105,"depth":518,"text":106},{"id":147,"depth":518,"text":148},{"id":198,"depth":518,"text":199},{"id":259,"depth":518,"text":260},{"id":308,"depth":518,"text":309},{"id":342,"depth":518,"text":343},{"id":390,"depth":518,"text":391},{"id":424,"depth":518,"text":425},{"id":461,"depth":518,"text":462},{"id":497,"depth":518,"text":498},"https://codebyquan.dev/blog/10-coding-practices-i-follow-every-project","Developer writing clean code and automated tests on dual monitors","2025-02-05T08:00:00.000Z","The non‑negotiable coding habits I use on client and personal projects—testing, git hygiene, documentation and performance.",null,"md","https://images.pexels.com/photos/3861964/pexels-photo-3861964.jpeg",{},10,true,{"title":10,"description":535},[544,545,546,547],"Best-Practices","Clean-Code","Testing","Career","fg9zZjO7AjG2tpglR9IZFRLEGNIbJPz0yCJ0hqlXYJ8",[536,550],{"title":14,"path":15,"stem":16,"description":551,"children":-1},"How I combine AI tools with real engineering judgment to ship faster, safer code—without replacing developers.",1773445098481]