ARCHITECTUREA Social Filesystem
Dan Abramov reframes the AT Protocol through the lens of personal computing's file paradigm: just as files belong to users rather than apps, social data should live in user-controlled repositories that any app can read and write. He walks through the protocol's core primitives — records (JSON files), collections (namespaced by reverse domain, e.g. com.twitter.post), lexicons (schema definitions), and at:// URIs that survive hosting and handle changes via DID-based identity. Apps become reactive views over a distributed "social filesystem"; deleting an at:// record from pdsls instantly disappears the corresponding Bluesky post. Practical demos include mounting a repository as a FUSE drive with pdsfs and querying cross-app data with lex-gql. The piece argues that an open ecosystem where "third-party is first-party" — exemplified by community-built feeds outperforming Bluesky's own algorithm — is a feature, not a bug.
Read Articlearrow_forward Article · AIREAD TIME: 31m
How to Write a Good Spec for AI Agents
Addy Osmani distills best practices from extensive use of coding agents including Claude Code and Gemini CLI into a five-principle framework for spec-writing. Key findings from GitHub's analysis of over 2,500 agent configuration files show effective specs consistently cover six areas: commands (with full flags), testing setup, project structure, code style with real examples, git workflow, and explicit boundaries. He advocates a three-tier boundary system (Always do / Ask first / Never do) — with "never commit secrets" being the single most common helpful constraint found in the study. Large specs should be decomposed into modular prompts, fed to subagents per domain, or summarized via hierarchical TOCs to avoid the "curse of instructions," where performance degrades as instruction count rises. The workflow mirrors spec-driven development: Specify → Plan → Tasks → Implement, with human review gating each phase.
READ_FULL_LOGarrow_forwardArticle · REACTREAD TIME: 11m
Can You Fetch Data with React Server Actions?
Nadia Makarevich investigates whether React Server Actions (now officially called Server Functions) can replace fetch for client-side data fetching — and delivers a definitive answer: technically yes, practically no. Using a real dashboard app with seven TanStack Query-backed endpoints, she benchmarks replacing all fetch calls with Server Actions and finds that what was 1.7s total data load time balloons to 8s. The culprit is documented React behavior: "frameworks implementing Server Functions typically process one action at a time," meaning parallel requests are serialized into a queue. Additional drawbacks include a confusing Network panel where all action calls share the same localhost endpoint name and responses appear as opaque RSC payloads. The conclusion is to keep REST + TanStack Query for client-side fetching and reserve Server Actions for mutations. An LCP comparison table covers Simple fetch (500ms), Server Actions (500ms LCP / 8s data), SSR (1.3s), and Server Components (520ms / 1.2s).
READ_FULL_LOGarrow_forwardArticle · ARCHITECTUREREAD TIME: 5m
When Protections Outlive Their Purpose: Managing Defense Systems at Scale
GitHub's Thomas Kjær Aabo recounts how incident-response rate-limit rules, intended as temporary emergency controls, quietly became permanent and began blocking legitimate users during normal, low-volume browsing. The protections used composite fingerprinting signals combining industry-standard techniques with GitHub-specific business logic; among requests matching the suspicious fingerprint, only 0.5–0.9% were actually blocked — but those were blocked 100% of the time, causing real disruption. Tracing root cause required correlating logs across edge, application, and protection-rule layers, each with different schemas. The post-mortem lesson: temporary mitigations must be treated as technical debt with explicit expiration dates, post-incident rule reviews, and ongoing impact monitoring. GitHub's remediation plan includes better cross-layer visibility, making permanence an intentional documented decision, and evolving emergency controls into targeted sustainable solutions.
READ_FULL_LOGarrow_forwardArticle · TESTINGREAD TIME: 10m
Vitest vs Jest: Why I Would Always Pick Vitest in 2026
Despite Jest still leading in weekly downloads (30M vs Vitest's 20M as of early 2026), the author argues Vitest is the better default for new projects today. The migration cost is nearly zero — only jest.* changes to vi.*— and Vitest's native ESM support eliminates the NODE_OPTIONS=--experimental-vm-modules workarounds or Babel/ts-jest transformers required by Jest. Vitest's browser mode lets tests run in a real Chromium/Firefox/Safari environment rather than a simulated JSDOM, and built-in TypeScript type assertions (expectTypeOf, assertType) have no Jest equivalent. Additional wins include the @vitest/ui browser dashboard, in-source testing via import.meta.vitest, and sharing the same vite.config.ts so test and production environments stay in sync. The recommendation: don't switch existing Jest projects for its own sake, but all new projects in 2026 should start with Vitest.
READ_FULL_LOGarrow_forwardArticle · PERFORMANCEREAD TIME: 3m
Improve Time to First Byte by Streaming Your HTML
Mauro Bieg demonstrates how HTTP streaming can dramatically reduce TTFB on dynamically generated pages that depend on database queries. The core problem: a typical await db.execute() blocks the entire response until the last row is returned, only then beginning HTML assembly and transmission. By switching to db.stream() — which returns an AsyncIterable instead of an array — the server can send the page header to the browser immediately, while the database is still processing remaining rows. The article shows a practical implementation using the Mastro server framework and Kysely ORM, where a custom mapIterable helper lazily transforms streamed rows into HTML chunks without blocking. HTTP streaming works natively in HTTP/2 and HTTP/3; in HTTP/1.1 it relied on chunked transfer encoding. The key constraint: no await anywhere in the chain from database driver to CDN proxy.
READ_FULL_LOGarrow_forwardsummarizeDigest_Summary
Week 3's general web-dev issue weaves together a coherent argument: the craft of building maintainable, performant web applications demands rigorous thinking about architecture, testing, and data flow — and that discipline is increasingly tested by the temptation to let AI agents do the thinking for you. The featured piece is Dan Abramov's "A Social Filesystem", a 25-minute architectural essay reframing the AT Protocol — used by Bluesky — as a distributed filesystem for social data. Records (JSON files), collections (reverse-domain namespaced), lexicons (schemas), and at:// URIs form a layer where apps become reactive views and user data survives hosting changes via DID-based identity. Practical demos include mounting a repo as a FUSE drive with pdsfs and cross-app queries with lex-gql.
Performance and data-fetching receive sharp scrutiny. Nadia Makarevich runs a definitive benchmark showing that using React Server Functions for data fetching serialises all requests into a queue — turning a 1.7s dashboard load into 8s — making REST + TanStack Query the correct choice for read paths and Server Actions the right tool only for mutations. Mauro Bieg demonstrates the complementary TTFB win: switching from await db.execute() to db.stream() (an AsyncIterable) lets the server flush the page head before the database finishes, slashing perceived load time with zero framework lock-in. Addy Osmani contributes a five-principle framework for writing AI agent specs — covering the three-tier boundary system (Always do / Ask first / Never do), modular prompt decomposition, and the spec-driven workflow — drawing on GitHub's analysis of 2,500+ agent configuration files.
Two items round out the issue with lessons about system longevity and testing defaults. A GitHub engineering post-mortem shows how temporary rate-limiting rules quietly become permanent and block legitimate users — the fix is treating temporary mitigations as technical debt with explicit expiration dates and ongoing monitoring. And a comparison of Vitest vs Jest argues Vitest is the correct default for all new 2026 projects: native ESM, real browser-mode testing (Chromium/Firefox/Safari), built-in expectTypeOf assertions, and a shared vite.config.ts — all with near-zero migration cost.
Key Takeaways- Dan Abramov's AT Protocol essay shows how user-controlled social data repositories (records, collections, at:// URIs) let apps become reactive views — a decentralised architecture where deleting a record instantly removes the corresponding post.
- React Server Functions serialise parallel data requests into a queue: benchmarks show a 1.7s dashboard load inflating to 8s; keep REST + TanStack Query for reads and Server Actions only for mutations.
- Switching from await db.execute() to db.stream() (AsyncIterable) lets the server flush the page head before the DB finishes, dramatically reducing TTFB without framework lock-in.