[{"data":1,"prerenderedAt":270},["ShallowReactive",2],{"post-readmes-that-get-projects-running":3,"blog-posts":14},{"_path":4,"title":5,"description":6,"date":7,"tags":8,"readingTime":12,"body":13},"\u002Fblog\u002Freadmes-that-get-projects-running\u002F","READMEs That Get Projects Running","How to write a README that helps someone—including future you—install, run, and understand a project without opening a support chat.","2024-12-18",[9,10,11],"documentation","open-source","habits",5,"# READMEs That Get Projects Running\n\nA README is the front door of a repository. If it cannot get a motivated stranger (or you, six months later) from clone to running app, the rest of the docs barely matter.\n\n## Lead with what it is and how to run it\n\nOpen with two blocks in this order: a one-paragraph description, then the shortest path to a working local run. Clever badges, screenshots, and philosophy can wait until those are solid.\n\nA strong opening answers:\n\n- What problem does this solve?\n- Who is it for?\n- What does success look like after install?\n\nThen give copy-pasteable commands. Prefer the boring sequence people will actually use:\n\n```bash\ngit clone \u003Curl>\ncd \u003Cproject>\nnpm install\nnpm run dev\n```\n\nIf there are required accounts, env files, or OS-specific steps, call them out *before* the happy-path commands fail. Nothing erodes trust faster than a README that pretends setup is one line when it quietly needs three secrets and a native toolchain.\n\nState versions when it matters—“Node 20+”—instead of “recent Node.” Pinning exact versions in the README is optional; naming the major line that you test against is not.\n\nIf the project has a live demo, put the URL near the top beside the description. People deciding whether to invest setup time should see the payoff early. Just do not let the demo link replace local run instructions—demos go down; clones should still work.\n\n## Document the real shape of the project\n\nAfter run instructions, sketch the map. Newcomers should not have to reverse-engineer folder meaning from filenames alone.\n\nUseful map ingredients:\n\n- What lives in `src\u002F`, `content\u002F`, `scripts\u002F`, or `public\u002F`\n- Which command builds, tests, lints, or deploys\n- Where configuration lives (and which files are generated vs edited)\n- How content or data enters the system (Markdown, JSON, API)\n\nKeep this section short. A README is not an architecture novel. Link deeper docs if you have them, but the map should stand alone for common tasks like “where do I add a blog post?” or “where do I change the theme?”\n\nCall out footguns explicitly. If `npm run generate` must follow a content update script, say so in the same breath. Tribal knowledge that only exists in your head will become a bug report later—from yourself.\n\nEnvironment variables deserve a dedicated mini-table or list: name, required or optional, example value, and where it is used. A `.env.example` file plus a README section that points to it beats scattering “set FOO” notes across unrelated headings. People should be able to configure without reading the entire source tree.\n\n## Write for scannability and honesty\n\nPeople skim READMEs under time pressure. Help them:\n\n- Use descriptive headings (`## Deploy to Cloudflare Pages`, not `## Misc`)\n- Put prerequisites in a list near the top\n- Separate “required” from “optional” tooling\n- Show expected output for ambiguous commands when helpful\n\nHonesty beats marketing. If a feature is experimental, label it. If Windows needs an extra step, document it instead of assuming Unix. If the project is a learning sandbox with sharp edges, say that up front so contributors calibrate effort.\n\nAvoid screenshots of terminal themes as a substitute for text commands. Images go stale, do not copy cleanly, and fail accessibility. A small UI screenshot of the running app can help orientation; setup steps should stay as text.\n\nInclude a minimal “Troubleshooting” subsection for the failures you have already hit twice: port in use, missing env var, wrong Node version, build needing a clean install. Three bullet fixes save hours of duplicated Slack threads—or silent abandonment.\n\nLicense and conduct belong as short pointers, not essays in the middle of setup. A one-liner—“MIT. See LICENSE.”—is enough in the README; keep the full text in its own file. Same for contributing guidelines once they outgrow a handful of bullets.\n\n## Maintain the README like product code\n\nREADMEs rot when only the code evolves. Treat doc drift as a defect.\n\nLightweight maintenance habits:\n\n- Update the README in the same PR as setup or script changes\n- Re-run the documented path on a clean folder before a tagged release\n- Delete instructions for removed scripts instead of commenting “old”\n- Keep a changelog or release notes elsewhere; do not turn the README into history soup\n\nFor portfolio and side projects, the README also doubles as a case study seed: problem, approach, stack, and live URL. That is fine—as long as the run path remains first. A beautiful narrative that cannot start the app is a brochure, not a README.\n\nIf you accept contributions, add a short “Contributing” pointer: how to branch, what checks must pass, and how to propose doc fixes. Many first PRs are documentation; welcoming that is how projects stay approachable.\n\n## Wrap-up\n\nA good README gets someone running quickly, orients them in the repo, stays scannable and truthful, and evolves with the code. Write the door you wish you had when returning cold to your own project—then keep it from falling off the hinges.",[15,24,34,43,50,57,64,72,79,86,93,101,108,115,122,130,136,144,153,161,167,174,180,188,196,203,209,215,222,228,234,240,247,254,261,263],{"_path":16,"title":17,"description":18,"date":19,"tags":20,"readingTime":12},"\u002Fblog\u002Fclient-side-tools-that-earn-trust\u002F","Client-Side Tools That Earn Trust","How to design browser tools that feel private by default—local processing, clear data boundaries, and UX that never asks people to guess where their files go.","2026-07-20",[21,22,23],"privacy","frontend","tools",{"_path":25,"title":26,"description":27,"date":28,"tags":29,"readingTime":33},"\u002Fblog\u002Fusb-c-cables-that-actually-matter\u002F","USB-C Cables That Actually Matter","How to buy USB-C cables by wattage and data speed so you stop guessing which cord charges slowly or fails a file transfer.","2026-07-14",[30,31,32],"gadgets","hardware","productivity",4,{"_path":35,"title":36,"description":37,"date":38,"tags":39,"readingTime":12},"\u002Fblog\u002Fcolor-contrast-people-can-read\u002F","Color Contrast People Can Actually Read","Quick checks for text and UI colors that stay legible in light mode, dark mode, and on mediocre displays.","2026-07-07",[40,41,42],"accessibility","css","design",{"_path":44,"title":45,"description":46,"date":47,"tags":48,"readingTime":12},"\u002Fblog\u002Fportable-ssds-worth-carrying\u002F","Portable SSDs Worth Carrying","When a pocket SSD beats cloud sync for travel, backups, and large media—and how to pick one that stays fast and durable.","2026-06-26",[30,49,32],"storage",{"_path":51,"title":52,"description":53,"date":54,"tags":55,"readingTime":12},"\u002Fblog\u002Fwireless-earbuds-that-last-the-day\u002F","Wireless Earbuds That Last the Day","Simple charging and fit habits that stretch earbud battery life without babysitting the case every few hours.","2026-06-18",[30,56,11],"audio",{"_path":58,"title":59,"description":60,"date":61,"tags":62,"readingTime":33},"\u002Fblog\u002Fwhen-a-second-monitor-helps\u002F","When a Second Monitor Actually Helps","A practical take on dual screens for coding, writing, and research—plus when a single good display is still the better desk.","2026-06-10",[30,32,63],"workspace",{"_path":65,"title":66,"description":67,"date":68,"tags":69,"readingTime":33},"\u002Fblog\u002Fshort-session-game-picks\u002F","Short-Session Games That Respect Your Evening","Genres and design patterns that fit a 30-minute window without the “one more hour” trap.","2026-06-04",[70,11,71],"gaming","indie",{"_path":73,"title":74,"description":75,"date":76,"tags":77,"readingTime":12},"\u002Fblog\u002Fphone-charging-habits-that-age-better\u002F","Phone Charging Habits That Age Better","Practical charging routines that keep a phone useful longer—without obsessing over the perfect battery percentage.","2026-05-23",[30,78,11],"mobile",{"_path":80,"title":81,"description":82,"date":83,"tags":84,"readingTime":12},"\u002Fblog\u002Ffinishing-side-projects-without-burning-out\u002F","Finishing Side Projects Without Burning Out","A practical playbook for shrinking scope, shipping thin vertical slices, and keeping personal projects fun long enough to actually launch.","2026-05-14",[32,85,11],"side-projects",{"_path":87,"title":88,"description":89,"date":90,"tags":91,"readingTime":12},"\u002Fblog\u002Faccessible-forms-people-finish\u002F","Accessible Forms That People Actually Finish","Practical accessibility checks for labels, errors, and focus so your forms work for more users.","2026-05-07",[40,92,22],"html",{"_path":94,"title":95,"description":96,"date":97,"tags":98,"readingTime":12},"\u002Fblog\u002Fvue-composition-api-patterns\u002F","Practical Vue Composition API Patterns","Reusable patterns for composables, shared state, and cleaner component logic in Vue 3.","2026-04-27",[99,100,22],"vue","javascript",{"_path":102,"title":103,"description":104,"date":105,"tags":106,"readingTime":12},"\u002Fblog\u002Fdesigning-empty-states-that-teach\u002F","Designing Empty States That Teach the Product","Empty screens are not placeholders—they are onboarding. How to write, layout, and sequence first-run UI so people know what to do next.","2026-04-19",[107,22,42],"ux",{"_path":109,"title":110,"description":111,"date":112,"tags":113,"readingTime":12},"\u002Fblog\u002Fwhy-indie-games-keep-winning\u002F","Why Indie Games Keep Winning Attention","How small teams punch above their weight with focused design, personality, and smart scope.","2026-04-13",[70,71,114],"industry",{"_path":116,"title":117,"description":118,"date":119,"tags":120,"readingTime":12},"\u002Fblog\u002Fkeeping-component-props-simple\u002F","Keeping Component Props Simple","When to split a component, when to use slots, and how to avoid prop objects that grow forever.","2026-04-03",[99,22,121],"best-practices",{"_path":123,"title":124,"description":125,"date":126,"tags":127,"readingTime":12},"\u002Fblog\u002Fcalm-frontend-performance\u002F","A Calm Approach to Frontend Performance","Performance work that sticks: measure what users feel, fix the critical path first, and avoid optimization theater on personal and portfolio sites.","2026-03-26",[128,22,129],"performance","web",{"_path":131,"title":132,"description":133,"date":134,"tags":135,"readingTime":12},"\u002Fblog\u002Fcss-layout-without-the-hacks\u002F","CSS Layout Without the Hacks","Modern Flexbox and Grid techniques that replace brittle floats, magic numbers, and overflow tricks.","2026-03-17",[41,22,42],{"_path":137,"title":138,"description":139,"date":140,"tags":141,"readingTime":12},"\u002Fblog\u002Fcloud-gaming-what-gets-in-the-way\u002F","Cloud Gaming: What Still Gets in the Way","Latency, input feel, and library lock-in—why streaming games is impressive and still uneven.","2026-03-10",[70,142,143],"cloud-gaming","tech",{"_path":145,"title":146,"description":147,"date":148,"tags":149,"readingTime":12},"\u002Fblog\u002Fshipping-static-sites-with-nuxt\u002F","Shipping Static Sites with Nuxt","How I build and deploy a Nuxt site to Cloudflare Pages with predictable routes and content.","2026-03-02",[150,151,152],"nuxt","ssg","devops",{"_path":154,"title":155,"description":156,"date":157,"tags":158,"readingTime":12},"\u002Fblog\u002Fdebugging-faster-in-the-browser\u002F","Debugging Faster in the Browser","A short toolkit of DevTools habits—breakpoints, network filters, and DOM inspection—that cut debug time.","2026-02-24",[100,159,160],"devtools","debugging",{"_path":162,"title":163,"description":164,"date":165,"tags":166,"readingTime":12},"\u002Fblog\u002Fsmall-javascript-habits-that-scale\u002F","Small JavaScript Habits That Scale","Everyday habits—naming, early returns, and clearer async flow—that keep front-end codebases maintainable.","2026-02-18",[100,121,22],{"_path":168,"title":169,"description":170,"date":171,"tags":172,"readingTime":33},"\u002Fblog\u002Fhealthier-gaming-routine\u002F","Building a Healthier Gaming Routine","Simple habits for sessions that stay fun—breaks, goals, and knowing when to stop.","2026-02-02",[70,11,173],"wellness",{"_path":175,"title":176,"description":177,"date":178,"tags":179,"readingTime":12},"\u002Fblog\u002Fresponsive-images-without-layout-shift\u002F","Responsive Images Without Layout Shift","Width, height, srcset, and lazy loading patterns that keep pages stable while images load.","2026-01-22",[92,128,22],{"_path":181,"title":182,"description":183,"date":184,"tags":185,"readingTime":12},"\u002Fblog\u002Fgit-habits-for-small-teams\u002F","Git Habits for Solo and Small Teams","Branch naming, commit messages, and PR hygiene that keep history useful without slowing you down.","2026-01-09",[186,187,32],"git","workflow",{"_path":189,"title":190,"description":191,"date":192,"tags":193,"readingTime":12},"\u002Fblog\u002Fwhat-makes-a-game-stream-worth-watching\u002F","What Makes a Game Stream Worth Watching","Commentary, pacing, and community—why some streams click even when the gameplay is messy.","2025-12-14",[70,194,195],"streaming","content",{"_path":197,"title":198,"description":199,"date":200,"tags":201,"readingTime":12},"\u002Fblog\u002Fwhen-to-reach-for-typescript-vue\u002F","When to Reach for TypeScript on a Vue App","A pragmatic take on where TypeScript pays off in Vue—and where plain JS is still fine.","2025-11-30",[202,99,22],"typescript",{"_path":204,"title":205,"description":206,"date":207,"tags":208,"readingTime":12},"\u002Fblog\u002Fenvironment-variables-for-static-sites\u002F","Environment Variables for Static Sites","How to use build-time env vars in Nuxt and other static generators without leaking secrets or breaking CI.","2025-10-05",[150,152,22],{"_path":210,"title":211,"description":212,"date":213,"tags":214,"readingTime":12},"\u002Fblog\u002Fpicking-a-side-project-stack\u002F","Picking a Side Project Stack Without Overthinking It","How to choose tools for a personal project when the goal is shipping, not building the perfect architecture.","2025-09-18",[32,22,121],{"_path":216,"title":217,"description":218,"date":219,"tags":220,"readingTime":33},"\u002Fblog\u002Fco-op-games-for-busy-friends\u002F","Co-op Games That Work When Everyone Is Busy","Async-friendly and drop-in co-op picks for friend groups that rarely share the same free evening.","2025-08-22",[70,221,11],"co-op",{"_path":223,"title":224,"description":225,"date":226,"tags":227,"readingTime":12},"\u002Fblog\u002Fsemantic-html-still-matters\u002F","Semantic HTML Still Matters","Landmarks, headings, and native elements that make pages easier to use, style, and maintain.","2025-07-06",[92,40,22],{"_path":229,"title":230,"description":231,"date":232,"tags":233,"readingTime":12},"\u002Fblog\u002Fgit-without-the-jargon\u002F","Learning Git Without the Jargon","A plain-language mental model for commits, branches, and merges when tutorials assume you already know Git.","2025-05-14",[186,187,32],{"_path":235,"title":236,"description":237,"date":238,"tags":239,"readingTime":12},"\u002Fblog\u002Fwhy-loading-states-matter\u002F","Why Loading States Matter More Than Animations","Skeletons, disabled buttons, and honest feedback beat flashy spinners when data takes time to arrive.","2025-03-28",[107,22,42],{"_path":241,"title":242,"description":243,"date":244,"tags":245,"readingTime":12},"\u002Fblog\u002Fnaming-things-so-future-you-survives\u002F","Naming Things So Future You Survives","Practical rules for naming variables, components, and files so a codebase stays readable months after the clever jokes fade.","2025-03-10",[100,121,246],"maintainability",{"_path":248,"title":249,"description":250,"date":251,"tags":252,"readingTime":12},"\u002Fblog\u002Fsave-systems-that-respect-time\u002F","Save Systems That Respect the Player’s Time","Checkpoints, autosaves, and manual slots are design choices. How thoughtful saving reduces rage-quits without deleting tension from the game.","2025-02-28",[70,253,107],"game-design",{"_path":255,"title":256,"description":257,"date":258,"tags":259,"readingTime":12},"\u002Fblog\u002Fmicrocopy-that-makes-interfaces-human\u002F","Microcopy That Makes Interfaces Feel Human","Button labels, error lines, and helper text are product design. How to write UI words that reduce hesitation without sounding like a chatbot.","2025-01-22",[107,260,42],"writing",{"_path":4,"title":5,"description":6,"date":7,"tags":262,"readingTime":12},[9,10,11],{"_path":264,"title":265,"description":266,"date":267,"tags":268,"readingTime":12},"\u002Fblog\u002Fprogressive-enhancement-still-pays-off\u002F","Progressive Enhancement Still Pays Off","Build the core experience in HTML first, then layer CSS and JavaScript so your site stays useful when networks, scripts, or devices misbehave.","2024-11-05",[92,22,269],"architecture",1784620505251]