{"version":"https://jsonfeed.org/version/1.1","title":"Pithy","language":"","home_page_url":"https://pithy.sh","feed_url":"https://pithy.sh/feed.json","description":"A backend kit. For Cloudflare. That's it.","icon":"https://pithy.sh/static/images/logo-2026-09-18T21-31-35-487Z.png","items":[{"id":"6f4bb582-4247-46fa-9d1c-1e5686023167","url":"https://pithy.sh/blog/a-seam-never-a-sibling/","title":"A seam, never a sibling","content_text":"One rule about what a capability may import, and what it buys — including why a management client gets its own request variable rather than borrowing the user's.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/bacc67ed-42e8-4de1-1afc-f55d36cb8300/original","date_published":"2026-06-09T12:00:00Z","date_modified":"2026-09-21T23:06:21Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"c25e1898-68d7-4379-b9d4-9201f172b6ce","url":"https://pithy.sh/blog/four-things-you-never-have-to-solve-on-d1/","title":"Four things you never have to solve on D1","content_text":"Parameter budgets, transient faults, SQLite's missing types and pagination that holds still under writes. Solved once in core, so every capability inherits them.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/fd759d12-685b-4a52-c9d7-d6a5e2e8be00/original","date_published":"2026-06-09T12:00:00Z","date_modified":"2026-09-21T23:06:22Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"7295dab5-34ca-4e48-a5b7-1c9e8a413526","url":"https://pithy.sh/blog/toolchain-and-customized-lint-rules/","title":"The toolchain, and customized lint rules","content_text":"TypeScript 7, Bun, Turborepo, tsdown, Vitest and Biome — including what the losing options still do better. Then the part that surprised us: GritQL plugins enforcing rules a type system cannot.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/0719abb9-7317-4a5d-ef23-c5bc42f1fe00/original","date_published":"2026-06-09T12:00:00Z","date_modified":"2026-09-21T23:06:24Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"a7dc34f7-7de9-43ef-b927-3720bbb8ba8b","url":"https://pithy.sh/blog/fifty-seven-round-trips-or-one/","title":"Fifty-seven round trips, or one","content_text":"Migrations composed per capability and ordered once — and a driver change that took 78% of a test suite's wall time back.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/b8d7871a-a2f6-4457-2e3d-ae1f5ad40d00/original","date_published":"2026-06-10T12:00:00Z","date_modified":"2026-09-21T23:06:26Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"e54ec8c2-566c-4089-b4a7-c3687e6cbe20","url":"https://pithy.sh/blog/typed-kv-and-metadata-that-repairs-itself/","title":"Typed KV, and metadata that repairs itself","content_text":"Keys built from a schema, values validated both ways, and a list that quietly repairs the metadata the Cloudflare dashboard throws away.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/94d50f3f-f4f9-4f85-8a66-e10c9c0c5a00/original","date_published":"2026-06-10T12:00:00Z","date_modified":"2026-09-21T23:06:27Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"8b28f099-473d-4316-a5ce-1df613732571","url":"https://pithy.sh/blog/an-error-that-knows-who-is-reading-it/","title":"The error that knows who is reading it","content_text":"One error type, one schema, and a wire shape with nowhere to put the things a caller must never see.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/4e083d7b-6222-4d71-2f9e-123fd306e800/original","date_published":"2026-06-11T12:00:00Z","date_modified":"2026-09-21T23:06:28Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"7f6212e0-92f0-40f6-be8d-1bc506fed825","url":"https://pithy.sh/blog/cli-is-a-product-surface/","title":"The CLI is a product surface","content_text":"Citty, picocolors and clack — chosen for cold start, size and how they fail — plus why every command owes `--json` to an agent driving it.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/1f20e7c7-5e57-4e60-118d-d6be798d9800/original","date_published":"2026-06-12T12:00:00Z","date_modified":"2026-09-21T23:06:30Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"b500e62a-4df6-4114-896c-80a2e33e58cc","url":"https://pithy.sh/blog/what-one-command-writes-and-what-it-refuses-to-guess/","title":"What one command writes, and what it refuses to guess","content_text":"`pithy add` installs a package, writes bindings across every environment, runs migrations — and refuses, loudly, in the two places where guessing would be worse than stopping.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/1b7aa5cf-de35-49f0-1436-e53b6f33fc00/original","date_published":"2026-06-12T12:00:00Z","date_modified":"2026-09-21T23:06:31Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"ef4ad3af-311f-4dee-a3b1-500415789e66","url":"https://pithy.sh/blog/creating-it-once-is-the-easy-half/","title":"Creating it once is the easy half","content_text":"Fifteen Cloudflare resource kinds, provisioned per environment — and the reaper, because eight orphaned secrets sat on a real account with nothing able to reclaim them.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/77899363-fb11-43a0-5614-0778a88d8b00/original","date_published":"2026-06-14T12:00:00Z","date_modified":"2026-09-21T23:06:33Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"d2f0710c-6c72-4fa7-bd61-96c1f836c0ea","url":"https://pithy.sh/blog/rolling-a-secret-and-the-failure-you-cannot-undo/","title":"Rolling a secret, and the failure you cannot undo","content_text":"Encrypted secrets with a master key that never leaves your Worker — and a rotation ordered around the one outcome no retry can repair.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/5f4d350b-b6d0-4331-1622-58043994e100/original","date_published":"2026-06-16T12:00:00Z","date_modified":"2026-09-21T23:06:35Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"237cd1cd-2372-495b-90b4-b6262185e388","url":"https://pithy.sh/blog/a-capability-with-no-tables-no-routes-no-bindings/","title":"A capability with no tables, no routes, no bindings","content_text":"Turnstile is the smallest thing in the kit: no state, no migrations, no middleware you did not ask for. What it demonstrates is how capabilities cooperate without importing each other.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/8f37f9d0-7096-45c9-10c7-42615a5d2500/original","date_published":"2026-06-19T12:00:00Z","date_modified":"2026-09-21T23:06:37Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"247cf12b-ab76-4026-af2d-a3659ad8f7f2","url":"https://pithy.sh/blog/mail-that-survives-a-worker-restart/","title":"Mail that survives a Worker restart","content_text":"Transactional and lifecycle email as durable, tracked jobs — with a suppression list you never wire up and can still read like any other table.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/505cb0d1-2d89-448e-6ee4-2ee8fbd2af00/original","date_published":"2026-06-19T12:00:00Z","date_modified":"2026-09-21T23:06:38Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"b84d8658-4809-4833-ba55-e12aac032463","url":"https://pithy.sh/blog/who-did-that-and-did-it-work/","title":"Who did that, and did it work","content_text":"A queryable audit trail in your own D1, written by capabilities that never import it — and by the CLI, attributed to the actual person holding the token.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/f93ebc7b-9db5-4f5e-8857-d655c3e60a00/original","date_published":"2026-06-19T12:00:00Z","date_modified":"2026-09-21T23:06:39Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"ae53d1dc-042e-4547-9479-b80e65d48a10","url":"https://pithy.sh/blog/token-first-auth-and-what-happens-when-one-is-stolen/","title":"Token-first auth, and what happens when one is stolen","content_text":"Sign-in that treats a phone and a browser as the same problem, refresh rotation that survives a race, and a replayed token that takes its whole family down with it.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/fc5bf7a1-d241-402b-3d13-49f9fce0e700/original","date_published":"2026-06-20T12:00:00Z","date_modified":"2026-09-21T23:06:41Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"c6023472-5f05-4515-b66c-8635e9fa85f4","url":"https://pithy.sh/blog/logs-you-can-query-not-lines-you-can-read/","title":"Logs you can query, not lines you can read","content_text":"One logger seam, two adapters, and every record carrying the build that produced it — so the first question you ask at 2am has an answer in the dashboard.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/ae2676bc-5ba2-40e4-cf92-8bc4b7781200/original","date_published":"2026-07-15T12:00:00Z","date_modified":"2026-09-21T23:06:43Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"cedd0604-ef6b-46a5-a17c-93cebc8c3e79","url":"https://pithy.sh/blog/uploads-that-never-touch-your-worker/","title":"Uploads that never touch your Worker","content_text":"Direct-upload URLs, one media record whatever the backend, and AI enrichment that runs as a Workflow because captioning is slow and fails.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/8f5df0c0-c2b3-448e-5674-9a324482fa00/original","date_published":"2026-07-16T12:00:00Z","date_modified":"2026-09-21T23:06:45Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"b280c992-c4f9-4470-a4cd-dc1916671675","url":"https://pithy.sh/blog/your-leaderboard-history-is-yours-to-keep/","title":"Your leaderboard history is yours to keep","content_text":"Boards whose window is a CRON expression, closed windows that stay in your own D1 in plain SQL, and routes that deny by default when auth is absent.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/a41e9f7e-34ec-4a35-4b18-0819aa767400/original","date_published":"2026-07-17T12:00:00Z","date_modified":"2026-09-21T23:06:46Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"97d72263-4957-48ca-a6c2-344b4afcc485","url":"https://pithy.sh/blog/server-holds-what-no-client-can-be-trusted-with/","title":"The server holds what no client can be trusted with","content_text":"Authoritative turn-based sessions on a Durable Object, three example games on a reusable pattern, and a wagering stack with provably-fair dice.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/6b58ab1f-701c-4019-975b-84e870d03200/original","date_published":"2026-07-23T12:00:00Z","date_modified":"2026-09-21T23:06:52Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"1e231428-1d1f-45ac-8d14-a5031bec5acc","url":"https://pithy.sh/blog/a-connected-cast-not-scattered-rows/","title":"A connected cast, not scattered rows","content_text":"Seed data where the same three people own connected records in every table — and three independent layers standing between a fixture and your production database.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/2648e9a8-cdaa-420c-ab9c-6a3402013b00/original","date_published":"2026-07-24T12:00:00Z","date_modified":"2026-09-21T23:06:54Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"81351fd7-defa-4f2c-8196-381b7d573fd8","url":"https://pithy.sh/blog/four-ways-to-find-an-opponent/","title":"Four ways to find an opponent","content_text":"Room codes, invites, a friend graph and a skill-bucketed queue — all ending at one session id, on two Durable Objects the CLI wires for you.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/2a9bf12a-70d3-41d2-1693-3af417c43300/original","date_published":"2026-07-27T12:00:00Z","date_modified":"2026-09-21T23:06:56Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"9302c45d-59b1-4482-a004-5fdbf2f28a07","url":"https://pithy.sh/blog/two-numbers-because-one-cannot-do-both-jobs/","title":"Two numbers, because one cannot do both jobs","content_text":"A skill rating that moves both ways and an experience total that only rises — plus three algorithms, and a deploy that fails if you wire a 1v1 rating to a four-player game.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/9019ddc8-e630-47a7-e2dc-ec51ba8cb400/original","date_published":"2026-07-27T12:00:00Z","date_modified":"2026-09-21T23:06:57Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"e61678a4-9211-4979-9c31-150c6e7878d4","url":"https://pithy.sh/blog/a-balance-that-cannot-go-negative/","title":"A balance that cannot go negative","content_text":"Atomic, idempotent movements with overdraft prevented by a database constraint — and holds, which are what make wagering safe.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/c1cb7aa8-f6b0-4efb-354d-d9db303df500/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:06:59Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"fe165f63-dafa-442b-8a4d-318cb8972af7","url":"https://pithy.sh/blog/a-users-file-cannot-execute-on-your-origin/","title":"A user's file cannot execute on your origin","content_text":"Files in your own R2 behind one seam — with server-derived keys, uploaded bytes treated as hostile on the way out, and a daily Workflow that reconciles both directions of orphan.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/1f33c4db-74b0-4149-61f9-02fc9aeb4300/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:00Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"db26babf-eff2-4eda-8914-fdc02d1ebda5","url":"https://pithy.sh/blog/filters-that-silently-return-less/","title":"The filter that silently returns less","content_text":"Vectorize returns partial results without telling you when a metadata index came after the vectors. Making filterable fields a schema decision is how you stop finding that out in production.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/4806d806-6a39-4b2d-f8a5-909335a59900/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:01Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"5a30f031-2aef-4666-a81c-900bc3c6119f","url":"https://pithy.sh/blog/front-end-knows-what-the-backend-composed/","title":"The front end knows what the backend composed","content_text":"One virtual module per capability, projected from the Worker's own config at build time — and a capability you did not compose resolving to `{ enabled: false }` instead of failing the import.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/324c228e-28af-4849-b766-116c308d8300/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:02Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"57ede757-20f4-40e3-9758-6ded939c53bb","url":"https://pithy.sh/blog/nothing-reads-unvalidated-input/","title":"Nothing reads unvalidated input","content_text":"Every route declares what it accepts and who may call it, on the route line. Two gates make that structural rather than a habit — and the second one had to resort to a probe.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/97543f4b-d3cb-487f-341f-e6ae81b08e00/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:03Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"f7ce2915-5276-40b2-98f0-5de8d8b19717","url":"https://pithy.sh/blog/screens-that-arrive-already-wired/","title":"Screens that arrive already wired","content_text":"Sign-in, OTP, paywall, pricing, subscription — scaffolded into your repo as source you own, and only the ones your Worker actually composes.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/f97f4137-e0b9-429c-e83a-c506e0dc5500/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:04Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"e84b9a8f-1374-44a8-a4f8-72ef79e4d3fd","url":"https://pithy.sh/blog/six-copies-of-a-one-liner/","title":"Six copies of a one-liner, and the field none of them could see","content_text":"Durable jobs on Cloudflare Workflows, and a duplicated line that reported adding five bindings it had silently declined to write.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/1d443ab0-584d-4247-adb2-8c28be7d5b00/original","date_published":"2026-07-29T12:00:00Z","date_modified":"2026-09-21T23:07:05Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"5fe3a0e1-a8d0-405d-8790-61edb6ddd2b5","url":"https://pithy.sh/blog/buy-on-ios-be-entitled-on-the-web/","title":"Buy on iOS, be entitled on the web","content_text":"Four payment rails converging on one entitlement in your own D1 — through an idempotent projection that makes a dropped call free and a replayed webhook harmless.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/f72023b5-02e7-455d-4972-93ebc6e94d00/original","date_published":"2026-07-30T12:00:00Z","date_modified":"2026-09-21T23:07:07Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"a167282a-9611-4e93-b673-8508c93df26d","url":"https://pithy.sh/blog/present-and-denying-by-default/","title":"Present and denying by default","content_text":"A management client reaching into your Worker with no data plane between — asymmetric keys you can revoke, 60-second scoped tokens bound to their own body, and rotation that cannot lock you out.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/9a3cdcff-ec53-49b3-dad7-b39376981300/original","date_published":"2026-07-30T12:00:00Z","date_modified":"2026-09-21T23:07:08Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"bae2fe3b-9591-4bbc-b3f2-17a1ac6215aa","url":"https://pithy.sh/blog/when-a-missing-provider-must-deny/","title":"When a missing provider must deny","content_text":"Two seams in core, built the same way and defaulting opposite ways — because one of them is a gate and the other is a record.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/48e3d785-ce6e-4d19-2aa4-9a443fe52300/original","date_published":"2026-07-30T12:00:00Z","date_modified":"2026-09-21T23:07:09Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"10e6cc34-79a3-46b8-bda7-1c5fef669759","url":"https://pithy.sh/blog/support-is-the-employee-you-cannot-hire/","title":"Support is the employee you cannot hire","content_text":"An inbound inbox in your own D1, classified on your own Workers AI binding, with every sender linked to the account and purchases you already know about.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/d7f5dd0a-8e0e-4f31-9023-e47d1fd5fb00/original","date_published":"2026-07-31T12:00:00Z","date_modified":"2026-09-21T23:07:11Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"4182eb5a-f266-402b-9872-a1a11a2e42fe","url":"https://pithy.sh/blog/twelve-testers-fourteen-days-and-no-screen-that-tells-you/","title":"Twelve testers, fourteen days, and no screen that tells you","content_text":"Google Play's closed-test requirement, run from your own event log — with every count honestly labeled an estimate, because no API exposes the real one.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/5ffaa214-d235-4e43-851d-8865c8077500/original","date_published":"2026-07-31T12:00:00Z","date_modified":"2026-09-21T23:07:11Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"5ae020d8-eb2e-4a76-9021-fd7459d2c6cb","url":"https://pithy.sh/blog/worker-says-unknown/","title":"The worker says: unknown","content_text":"A string written out in four places, a name truncated against a limit that does not exist, and what both have in common.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/f2ac0081-c469-49e9-c3b6-42e212006100/original","date_published":"2026-08-03T12:00:00Z","date_modified":"2026-09-21T23:07:13Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"481b0fbc-f938-4dcf-8f83-4c507d80fac3","url":"https://pithy.sh/blog/ada-and-ada-are-the-same-person/","title":"Ada@ and ada@ are the same person","content_text":"Two primitives that look too small to be worth writing about — and the bugs they cause, which never look like they are about email addresses or version numbers.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/f021c6f8-2e0d-4ca2-4694-ec1187b25d00/original","date_published":"2026-08-11T12:00:00Z","date_modified":"2026-09-21T23:07:15Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"899f3350-49d2-464b-afdd-e106fa033477","url":"https://pithy.sh/blog/zero-of-twenty-five-conversations/","title":"Zero of twenty-five conversations","content_text":"One schema, two consumers, and why a strict enum is correct for the Worker that wrote it and wrong for the client that reads it.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/6c724fa5-0855-4ee0-07b2-e0a3c1fd2400/original","date_published":"2026-08-13T12:00:00Z","date_modified":"2026-09-21T23:07:16Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"84ca6367-0967-45c1-a48b-b56c099fb08b","url":"https://pithy.sh/blog/schemas-are-the-documentation/","title":"The schemas are the documentation","content_text":"One rule about Zod, enforced nineteen times by nineteen copies of the same walk. They drifted, and the worst of them passed by not looking.","banner_image":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/fd9d97e9-cb9e-4550-5e24-d07a55580500/original","date_published":"2026-08-15T12:00:00Z","date_modified":"2026-09-21T23:07:18Z","authors":[{"name":"Jim Scott","avatar":"https://pithy.sh/cdn-cgi/imagedelivery/CkSmQAGqpZ-mcWDDI6mu0w/17ead1c8-4705-40e8-247e-54d8f24c3800/profile"}]},{"id":"7139e9f6-206a-42bf-ab3f-e8d182d49561","url":"https://pithy.sh/modules/","title":"Modules","content_text":"Capabilities that compose into your own Cloudflare Worker. Add the ones you need; nothing you skip costs you anything.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z"},{"id":"f0bd6d80-1008-4724-b9b9-4b4b5d99026c","url":"https://pithy.sh/modules/audit/","title":"Audit","content_text":"A queryable trail of every security-relevant action, attributed to the right actor.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Enterprise"]},{"id":"be74d17c-c675-4fe7-960f-810970ecaeb2","url":"https://pithy.sh/modules/auth/","title":"Auth","content_text":"Passwordless sessions, mobile and web both first-class. Magic link, email OTP, Google, Apple.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games","Solo Builders","Mobile apps","Enterprise"]},{"id":"703920ba-d340-4e29-8c90-12774e8b4450","url":"https://pithy.sh/modules/controlplane/","title":"Control plane","content_text":"Let a management client reach into your own Worker, with no data plane in between.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Enterprise","Solo Builders"]},{"id":"17547693-5f9f-423e-bcbe-92cfebbae8df","url":"https://pithy.sh/modules/email/","title":"Email","content_text":"Every send is a durable job: scheduled, retried, tracked. No mail ever sent inline.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Enterprise"]},{"id":"894f423c-2425-4d3d-b32b-c5ae33602712","url":"https://pithy.sh/modules/lakehouse/","title":"Lakehouse","content_text":"An analytical tier for event and telemetry data — one schema object derives the ingest stream, the table and the query types.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Enterprise"]},{"id":"326e86b9-78d2-43b0-a48b-9fd07056dbca","url":"https://pithy.sh/modules/leaderboard/","title":"Leaderboard","content_text":"Rank your players. Submit a score, read the standings — daily through all-time.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games"]},{"id":"22b7a84d-1148-4507-90dc-dd66ba4b74cc","url":"https://pithy.sh/modules/ledger/","title":"Ledger","content_text":"A per-user balance for your app's economy — chips, gold, gems, credits. Correct by construction.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games","Mobile apps","Solo Builders"]},{"id":"807e51a6-d068-4efd-bf61-54efefb04415","url":"https://pithy.sh/modules/matchmaking/","title":"Matchmaking","content_text":"Room codes, invites, friends and matched queues. Every path lands players in one session.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games"]},{"id":"e85db005-3cb2-496e-9e8d-3eb29256e024","url":"https://pithy.sh/modules/media/","title":"Media","content_text":"Store, track and enrich images, video, audio and documents. Config picks the backend.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Mobile apps"]},{"id":"0531d22c-b884-487c-87e7-6cac879d9774","url":"https://pithy.sh/modules/multiplayer/","title":"Multiplayer","content_text":"Authoritative sessions on Durable Objects. The server holds what no client can be trusted with.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games","Mobile apps"]},{"id":"8b4b1d64-6a01-432e-b298-d0c8dbed4805","url":"https://pithy.sh/modules/payments/","title":"Payments","content_text":"Five payment rails resolving to one cross-rail entitlement, in your own Worker and your own D1.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games","Solo Builders","Mobile apps"]},{"id":"bfd5f1b5-e8f0-457d-a361-cf1ab59878e7","url":"https://pithy.sh/modules/rating/","title":"Rating","content_text":"Skill and experience per player, per pool. Elo, Glicko-2 and TrueSkill ship built in.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games"]},{"id":"d69bc64b-df6d-41df-8c0f-54769d194658","url":"https://pithy.sh/modules/secrets/","title":"Secrets","content_text":"One encrypted store per environment, a worker-only master key, and automatic at-rest rotation.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Enterprise"]},{"id":"c75f1234-a748-4de6-b5c9-31ddeb4a9578","url":"https://pithy.sh/modules/storage/","title":"Storage","content_text":"General file storage in your own R2 bucket, with an owner, a quota, and a link you can take back.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Mobile apps","Enterprise"]},{"id":"0b0af74f-3d08-4fab-8d38-3f2840ef4742","url":"https://pithy.sh/modules/support/","title":"Support","content_text":"An inbox that lands mail in your own D1, classifies it on your own AI, and knows who sent it.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Mobile apps","Enterprise"]},{"id":"291a07b3-2cb4-4203-9d4b-111ca3ec4e07","url":"https://pithy.sh/modules/testers/","title":"Testers","content_text":"The roster, the invitations and the fourteen-day clock Google Play makes you run.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Games","Mobile apps","Solo Builders"]},{"id":"79d322f5-f090-4d58-ad62-af24fc4a4dc6","url":"https://pithy.sh/modules/turnstile/","title":"Turnstile","content_text":"A humanity check that stacks on any route. It answers is this a human, never who is this.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Enterprise"]},{"id":"d8c72286-d383-4c52-8ef6-cd048978458d","url":"https://pithy.sh/modules/vector/","title":"Vector","content_text":"Semantic search over your own content. Workers AI embeds, Vectorize indexes, D1 keeps the text.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z","tags":["Solo Builders","Enterprise"]},{"id":"f0b08fa3-5100-4654-8529-2b27fa2b4dad","url":"https://pithy.sh/modules/i18n/","title":"i18n","content_text":"Language for your app — negotiated per request, rendered through one seam. No tables, no bindings, no error codes of its own.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z","tags":["Games","Solo Builders","Mobile apps","Enterprise"]},{"id":"02c631c4-b076-48da-bd07-dbf5e1599291","url":"https://pithy.sh/for/","title":"Solutions","content_text":"The same kit, recomposed for what you are building.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z"},{"id":"4919cff0-3cb7-4afe-9239-e2444a90ced9","url":"https://pithy.sh/for/enterprise/","title":"Enterprise","content_text":"An audit trail, encrypted secrets with automatic rotation, a humanity check, and a management plane that never holds your data.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-20T12:00:00Z"},{"id":"2de13917-0142-45e2-aa3c-b389206c0606","url":"https://pithy.sh/for/games/","title":"Games","content_text":"Authoritative sessions, matchmaking, skill rating, leaderboards and an economy — on Durable Objects and your own D1.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-20T12:00:00Z"},{"id":"825368b6-6e13-4393-905b-a0ebdf5753d7","url":"https://pithy.sh/for/mobile/","title":"Mobile apps","content_text":"Sign in with Apple and Google, StoreKit and Play Billing resolving to the same entitlement as the web, token-first sessions, and the Play closed-test clock nobody warns you about.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-20T12:00:00Z"},{"id":"d82c9f5a-41b2-4502-9026-75281fbb9aae","url":"https://pithy.sh/for/solo/","title":"Solo builders","content_text":"Payments on five rails, a support inbox, transactional mail and a scaffolded front end — the work a single person cannot hire out.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-20T12:00:00Z"},{"id":"b979e1af-e36f-4a6d-b4b7-c89ebc538b89","url":"https://pithy.sh/compare/","title":"Alternatives","content_text":"Already on something else? These pages lay out where Pithy is the better call — and where the tool you already have is the one to keep.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z"},{"id":"0b18f475-2e07-4073-9faf-9820f090ebaf","url":"https://pithy.sh/compare/supabase/","title":"Supabase vs Pithy","content_text":"Supabase is a managed Postgres platform. Pithy is a composable kit that runs entirely inside your own Cloudflare account. Here is the honest side-by-side.","date_published":"2026-08-18T12:00:00Z","date_modified":"2026-08-18T12:00:00Z"},{"id":"6b67c51a-d751-43eb-9495-2785f0c6b189","url":"https://pithy.sh/compare/algolia/","title":"Algolia vs Pithy","content_text":"Algolia is a hosted search product with latency nobody else matches. Pithy has semantic search as one capability. Compared on search alone.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"e98c049c-f1f8-42c4-a08d-4340295ae3f5","url":"https://pithy.sh/compare/appwrite/","title":"Appwrite vs Pithy","content_text":"Appwrite is an open-source backend you can self-host or buy managed. Pithy is a kit that composes onto Cloudflare's primitives inside your own account. Both answer ownership; they answer it differently.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"2d57d5f3-7c10-4134-af02-ece50d2d5b5a","url":"https://pithy.sh/compare/auth0/","title":"Auth0 vs Pithy","content_text":"Auth0 is the enterprise identity platform. Pithy has auth as one capability among many. Compared on auth alone — and on whether the compliance surface you are buying is one you actually need.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"6e88f33c-1c75-47e1-979d-b02dba722ba6","url":"https://pithy.sh/compare/aws-amplify/","title":"AWS Amplify vs Pithy","content_text":"Amplify is a TypeScript-first framework that provisions AWS services for you — Cognito, AppSync, DynamoDB, S3, Lambda. Pithy is a kit that provisions Cloudflare primitives. Same idea, different cloud, different amount of it.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"5392397d-0c4f-4461-a239-c4e9455d723d","url":"https://pithy.sh/compare/clerk/","title":"Clerk vs Pithy","content_text":"Clerk is a hosted identity product with the best drop-in components in the category. Pithy has auth as one capability among many. Compared on auth alone — and on whether you need a second vendor for it.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"b7a948d1-6a1e-4538-8a70-235ca5cc2054","url":"https://pithy.sh/compare/cloudinary/","title":"Cloudinary vs Pithy","content_text":"Cloudinary is a media pipeline with transformations nobody else matches. Pithy has media and storage as capabilities. Compared on media alone.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"96597966-b7b2-47e5-9376-12743edfa3f6","url":"https://pithy.sh/compare/colyseus/","title":"Colyseus vs Pithy","content_text":"Colyseus is an open-source Node framework for authoritative game servers, with rooms, state synchronization and matchmaking. Pithy has turn-based sessions as one capability. Compared on multiplayer alone.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"7e05cfe9-6bbe-4f4c-97ef-03a7a87cbb01","url":"https://pithy.sh/compare/convex/","title":"Convex vs Pithy","content_text":"Convex is a reactive backend where TypeScript functions run against a document store that pushes changes to clients. Pithy is a kit that composes onto Cloudflare's own primitives. Here is the honest side-by-side.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"52d7adbe-abd0-4ef4-8f17-c342df45f02e","url":"https://pithy.sh/compare/firebase/","title":"Firebase vs Pithy","content_text":"Firebase is Google's managed backend, and the fastest way to ship a mobile app there has ever been. Pithy is a kit that runs inside your own Cloudflare account. Here is the honest side-by-side.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"1363a8d9-93d3-45c4-a9c5-1137b133c4e2","url":"https://pithy.sh/compare/lootlocker/","title":"LootLocker vs Pithy","content_text":"LootLocker is a hosted game backend for leaderboards, progression and player economy. Pithy has those as capabilities in a Worker you own. Compared on the game services alone.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"47d354ce-bdf2-4ddf-8591-ae78a537e562","url":"https://pithy.sh/compare/nakama/","title":"Nakama vs Pithy","content_text":"Nakama is an open-source game server with accounts, storage, realtime multiplayer, matchmaking, leaderboards, tournaments, parties and chat. Pithy has the asynchronous half in a Worker you own.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"95cc1319-9456-47cc-99c0-67d86366f360","url":"https://pithy.sh/compare/nhost/","title":"Nhost vs Pithy","content_text":"Nhost is Postgres and Hasura with auth, storage and functions around them — GraphQL-first and self-hostable. Pithy composes onto Cloudflare's primitives with SQL and HTTP. Both are open source.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"22dabaa1-bab9-4e0f-bcf4-bad8295e16cd","url":"https://pithy.sh/compare/photon/","title":"Photon vs Pithy","content_text":"Photon is real-time networking for games — Fusion, Quantum and Realtime — priced on concurrent users. Pithy has turn-based multiplayer as one capability. Compared on multiplayer alone.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"068b02ce-38d4-4c10-856a-2bc7d9212cdf","url":"https://pithy.sh/compare/playfab/","title":"PlayFab vs Pithy","content_text":"PlayFab is Microsoft's complete backend for live games — identity, economy, matchmaking, dedicated servers, LiveOps and analytics. Pithy has the game capabilities in a Worker you own. Compared honestly.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"fb8fef2f-1568-4a86-aaa0-21cdd53e2fe7","url":"https://pithy.sh/compare/pocketbase/","title":"PocketBase vs Pithy","content_text":"PocketBase is one Go binary with SQLite, auth, files, realtime and an admin UI. Pithy is a kit that composes onto Cloudflare's primitives. Both are SQLite; almost nothing else is the same.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"c398cc29-ede5-474c-a0aa-33de32e07bf0","url":"https://pithy.sh/compare/revenuecat/","title":"RevenueCat vs Pithy","content_text":"RevenueCat is the best hosted answer to cross-platform purchases. Pithy has payments as one capability. Compared on subscriptions alone — and on where your customers' purchase history lives.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"},{"id":"3430912c-1e0b-4f81-8a29-f88d0a47429a","url":"https://pithy.sh/compare/rolling-your-own/","title":"Rolling your own vs Pithy","content_text":"The most common alternative, and sometimes the right one. What you actually take on when you write the backend yourself, and where a kit earns its place.","date_published":"2026-08-25T12:00:00Z","date_modified":"2026-08-25T12:00:00Z"}]}