[{"data":1,"prerenderedAt":112},["ShallowReactive",2],{"$fIJbaSCQjIxZfhfbEvMkpyy1HgWyAgiZzjO9nuPWuYQE":3,"$fBlxhEB79sIxoHmSdusMn7Lo7vCPJYfaUbbd2ytPieUo":20},{"success":4,"data":5},true,[6,9,12,14,16,18],{"count":7,"tag":8},2,"Open Source",{"count":10,"tag":11},1,"Cloudflare",{"count":10,"tag":13},"JavaScript",{"count":10,"tag":15},"R2",{"count":10,"tag":17},"curl",{"count":10,"tag":19},"Devops",{"success":4,"data":21,"pagination":109},[22,47,70,89],{"_id":23,"title":24,"slug":25,"contentType":26,"tags":27,"status":28,"seo":29,"viewCount":33,"likeCount":34,"readingTime":35,"defaultLanguage":36,"createdAt":37,"updatedAt":38,"excerpt":39,"coverImage":40,"publishedAt":41,"author":42,"availableLanguages":44},"6ab236b82e56af1fc98fd6c0","Cloudflare R2: the bill doesn't go away, it moves","cloudflare-r2-billing","html",[11,15,19],"published",{"metaTitle":30,"metaDescription":31,"metaKeywords":32},"Cloudflare R2 pricing: Class A and Class B","Why egress is free on R2, what Class A and Class B operations actually mean, and what it means that the bill moves from gigabytes to request counts.",[11,15,19],39,8,5,"tr","2026-09-22T08:05:12.717Z","2026-09-29T17:14:06.471Z","No egress fee, and that's true. But in Cloudflare's own example storage is zero, writes are zero, and the bill is $104. Where does it come from?","https://cdn.batuhanbas.dev/blog/covers/1790585010070-90315f89-18ca-425d-a3f5-c16534a6a8d6.webp","2026-09-28T08:48:08.583Z",{"name":43},"Batuhan Baş",[45,36,46],"en","ar",{"_id":48,"title":49,"slug":50,"contentType":26,"excerpt":51,"tags":52,"status":28,"seo":57,"viewCount":61,"likeCount":62,"readingTime":63,"defaultLanguage":36,"createdAt":64,"updatedAt":65,"coverImage":66,"publishedAt":67,"author":68,"availableLanguages":69},"6a94dd97cb83796db4dc881d","The framework war ended and nobody noticed","framework-war-is-over","No significant new frontend framework shipped in 2025. But the real change was never happening on the framework side anyway.",[53,54,13,55,56],"Frontend","CSS","Vite","Web Platform",{"metaTitle":58,"metaDescription":59,"metaKeywords":60},"Frontend 2026: the browser changed, not the framework","From State of JS 2025: Vite 8 and Rolldown, the Next.js satisfaction drop, CSS features reaching Baseline, and why CSS is resisting AI.",[53,54,13,55,56],84,50,6,"2026-08-31T01:49:11.227Z","2026-09-29T17:14:06.506Z","https://cdn.batuhanbas.dev/blog/covers/1788142749534-8464bbfb-0284-4c68-a90a-dfe26236470e.webp","2026-08-31T02:23:29.503Z",{"name":43},[45,36,46],{"_id":71,"title":72,"slug":73,"contentType":26,"excerpt":74,"tags":75,"status":28,"seo":78,"viewCount":82,"likeCount":83,"readingTime":63,"defaultLanguage":36,"createdAt":84,"updatedAt":85,"coverImage":86,"publishedAt":84,"author":87,"availableLanguages":88},"6a896a6cf2037887a38e21ec","Contributions have never been higher. That's the problem.","open-source-maintainer-crisis","Open source contributions hit records in 2025. In January 2026, four major projects narrowed their doors. Both are true, for the same reason.",[8,76,77,17],"AI","Software Culture",{"metaTitle":79,"metaDescription":80,"metaKeywords":81},"The open source maintainer crisis, explained","Why curl ended its bug bounty, what AI-generated contributions broke on the maintainer side, and why record contribution volume and closures happen together.",[8,76,77,17],104,16,"2026-08-22T09:22:52.568Z","2026-09-29T17:14:06.535Z","https://cdn.batuhanbas.dev/blog/covers/1787390837814-a7c5a567-dc28-4d4b-a89a-335db0e70085.webp",{"name":43},[45,36,46],{"_id":90,"title":91,"slug":92,"contentType":26,"excerpt":93,"tags":94,"status":28,"seo":97,"coverImage":101,"viewCount":102,"likeCount":103,"readingTime":35,"defaultLanguage":36,"createdAt":104,"updatedAt":105,"publishedAt":106,"author":107,"availableLanguages":108},"6a86af50d4d07b7fff86abd3","The Node.js inconsistency that sat open for four years","nodejs-timerify-inconsistency","timerify() skips the histogram when a function throws, but records it when an async one rejects. A confirmed bug that waited four years.",[95,96,8],"Node.js","Javascript",{"metaTitle":98,"metaDescription":99,"metaKeywords":100},"Node.js timerify() inconsistency explained","Why timerify() records rejected promises but not sync throws: Promise.finally vs then, the minimal thenable contract, and a four-year-old Node issue.",[95,96,8],"https://cdn.batuhanbas.dev/blog/covers/1787211312262-8079970a-061a-4ba2-be7c-648d674c126d.webp",156,11,"2026-08-20T07:40:00.768Z","2026-09-29T17:14:06.539Z","2026-08-20T07:40:00.769Z",{"name":43},[45,36,46],{"page":10,"limit":34,"total":110,"totalPages":10,"hasNext":111,"hasPrev":111},4,false,1790708003662]