# Wellworn verdicts, in the form the MCP returns them # 25 served verdicts, generated 2026-09-08 # Verdicts are CC BY-SA 4.0. Source and provenance for each one are on its page. URL https://wellworn.dev/verdicts/transactional-email-solo VERDICT transactional email provider for a small app, sign-up and receipt mail only PICK Resend 6.26.0: Resend 6.26.0. The free tier is 3,000 emails a month capped at 100 a day across 3 domains, the API is one POST, and React Email renders the templates. If deliverability matters more than developer experience, Postmark is the better sender and its free developer plan is only 100 emails a month with no tier between that and the 10,000 plan at 15 dollars. ALT Postmark: ZeptoMail sells credits rather than a subscription, one credit covering 10,000 emails and valid for six months, and the first credit is free.; wins when your volume is lumpy or tiny and you would rather pre-buy than hold a monthly plan TRAPS (1) [8ad9a8ec] major: A launch day burst stops sending after 100 messages even though the monthly quota is barely touched. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/testing-nextjs-app VERDICT test stack for a Next.js app, unit and end to end PICK Vitest 5.0.0: Vitest 5.0.0 for functions and components, Playwright 1.63.0 for the flows that make you money. Vitest reuses your Vite config so path aliases and TypeScript work without a second build, and Playwright drives real Chromium, Firefox, and WebKit with traces you can open after a CI failure. Skip a unit test for a server component that only awaits a query and reads props; test the query and the page instead. TRAPS (3) [e15de1d3] major: Vitest 5 refuses to start on Node 20, or on a project pinned to Vite 6.3 or older. [71e524a6] major: A test that relied on mock call history from a previous test starts failing after upgrading to 5. [619a3d53] minor: A test run in a monorepo package picks up no config and behaves as if options were ignored. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 3 URL https://wellworn.dev/verdicts/server-state-react VERDICT fetching and caching server data in a React app that already uses server components PICK TanStack Query 5.102.8: Start with server components and no client cache at all: fetch in the server component, mutate in a server action, and let the framework revalidate. Add TanStack Query 5.102.8 only for the screens that need polling, infinite scroll, optimistic updates, or offline retry, and keep the rest on the server. ALT SWR: SWR 2.5.1 is smaller and its stale-while-revalidate defaults cover read-mostly dashboards with less API to learn.; wins when you only need cached reads with revalidate-on-focus and no mutation machinery TRAPS (2) [c6b2d461] major: Code ported from v4 breaks: onSuccess on useQuery does nothing, cacheTime is unknown, isLoading changed meaning. [c133c4ac] minor: An infinite query throws at runtime because initialPageParam is missing. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 3 URL https://wellworn.dev/verdicts/search-small-app VERDICT search for a small app, a few hundred thousand documents with typo tolerance and filters PICK Meilisearch v1.53.2: Start with Postgres full-text search. `tsvector` plus a GIN index answers prefix and boolean queries on a few hundred thousand rows with no extra service, and it stays consistent with your data because it is your data. Move to Meilisearch v1.53.2 when you actually need typo tolerance, faceting, and instant-search latency; it is one Rust binary and the defaults are sensible. ALT Typesense: Typesense v30.2 is the closer match if you also want vector or hybrid search, and it publishes concrete sizing: roughly 2 to 3 times your searchable data in RAM, and at least 2 vCPUs.; wins when you need vector or hybrid search alongside keyword search, or you want a GPL-licensed engine TRAPS (2) [cf2934aa] major: Pagination past result 1000 returns nothing, with no error from the API. [269a36c0] minor: A long natural-language query matches oddly, as if part of it were ignored. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/react-component-system VERDICT component system for a React app you will style yourself PICK shadcn/ui 4.21.0: shadcn/ui, CLI 4.21.0. The components are copied into your repo as source, so restyling a button is editing a file rather than fighting a theme API, and there is no runtime dependency to upgrade in lockstep. The cost is real: you now own that code, including its accessibility bugs, and there is no upgrade command beyond re-running `add` and reading the diff. ALT Mantine: Mantine 9.6.0 gives you around a hundred maintained components plus hooks, dates, forms, and charts, with one version to bump.; wins when you need date pickers, rich tables, and notifications now and do not want to own their source TRAPS (1) [9c7f0fb2] minor: A component added today imports `cn` from a package while your older files define it locally. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/rate-limiting-and-cache VERDICT rate limiting and caching for a small app, in-process or Redis or Valkey PICK Valkey 9.1.2: Valkey 9.1.2 over Redis. Same protocol, same clients, BSD licensed by the Linux Foundation, and no question about what happens if you ever offer the thing you built as a service. Do the limiting in a Lua script so the read and the write are one round trip, because a GET followed by a SET is a race that lets a burst through. ALT Redis Open Source: Redis Open Source 8.10.1 added AGPLv3 alongside RSALv2 and SSPLv1 in 8.0.0, so a self-hosted Redis is OSI-licensed again if you accept AGPL's network clause.; wins when you depend on a Redis module or a managed Redis your provider already runs TRAPS (1) [eca99b22] major: A limiter built on GET then SET lets a burst through under concurrency. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/payments-stripe-availability VERDICT can you actually use Stripe for a SaaS if you are not incorporated in the US or EU PICK Paddle Billing 2026-09: Check the country list before you design anything. Stripe is fully launched in 48 countries, India and Indonesia are in beta, and several African markets are served through Paystack rather than Stripe itself. Algeria, Morocco, Egypt, Pakistan, and Vietnam are on none of those lists, so a company incorporated there cannot open a Stripe account at all. Accepting a customer's card is not the problem; getting paid out is. ALT Stripe: Paddle is a merchant of record, so it is Paddle's entity that sells to your customer and Paddle that pays you, by wire or Payoneer, which is what makes it work from countries Stripe has never launched in.; wins when your company is incorporated outside Stripe's 48 launched countries, or you want tax handled for you TRAPS (2) [89b40e6e] blocker: Selling AI-generated content or image generation through Paddle triggers an acceptable-use review and held payouts. [d9a9cbdb] major: Deleting a Paddle discount archives it; recreating one with the same code returns 409. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 3 URL https://wellworn.dev/verdicts/payments-merchant-of-record-indie VERDICT Paddle vs Polar vs Lemon Squeezy as merchant of record for an indie SaaS selling worldwide PICK Paddle Billing Paddle Billing API 2026-09: Paddle Billing if you need payouts outside the Stripe Connect countries (Paddle pays by wire or Payoneer) or the widest tax coverage; the 5% + $0.50 fee is all-in with no international surcharge. Usage pricing is done as flat tiers plus one-time credit products and reported through the subscription charge endpoint. ALT Polar: Polar is open source, has native usage-based billing and entitlements, and starts at 4%, but pays out only through Stripe Connect Express, so founders outside Stripe's supported countries cannot receive money.; wins when you are in a Stripe Connect country, want usage metering built in, and prefer an open-source vendor AVOID Lemon Squeezy: Lemon Squeezy (Stripe-owned since 2024) still has no Payoneer payout and its international subscription rate lands around 7% + $0.50 once surcharges apply; fine for one-time digital products, weaker for global SaaS. TRAPS (2) [89b40e6e] blocker: Selling AI-generated content or image generation through Paddle triggers an acceptable-use review and held payouts. [d9a9cbdb] major: Deleting a Paddle discount archives it; recreating one with the same code returns 409. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/orm-sqlite-typescript VERDICT TypeScript query layer for SQLite, Drizzle vs Prisma vs Kysely PICK Drizzle ORM 0.45.2: Drizzle ORM 0.45.2. SQLite is a first-class dialect, migrations are plain SQL files you can read in a pull request, and the driver list covers better-sqlite3, node:sqlite, Bun, and Turso, so the same schema moves from a local file to hosted SQLite. Kysely 0.29.5 is the better pick if you want a query builder and nothing else, with no migration tooling opinions attached. ALT Kysely: Prisma gives you a generated client and Prisma Studio, which is the friendlier path if you would rather not write SQL.; wins when you want a GUI over the data and a generated client more than control over the query TRAPS (3) [5f5f7185] major: Two app replicas start at once and both run migrations; the second fails on an already-applied step. [09f0b33a] major: Installing `drizzle-orm@rc` pulls 1.0.0-rc.5 and SQLiteSyncDialect no longer exists. [b7dc865f] minor: Selecting into a destructured tuple with `noUncheckedIndexedAccess` produces a type error on the first row. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/orm-postgres-typescript VERDICT Drizzle vs Prisma for a TypeScript app on Postgres PICK Drizzle ORM 0.45.2: Drizzle. The schema is TypeScript you can read, queries look like the SQL they become, the runtime adds about 20 KB with no engine to warm up, and migrations are plain SQL files you can review in a PR. ALT Prisma: Prisma has the more mature studio, a larger tutorial base, and generated types that beginners find easier.; wins when your team is new to SQL and wants Prisma Studio and the generated client more than control over queries TRAPS (3) [5f5f7185] major: Two app replicas start at once and both run migrations; the second fails on an already-applied step. [09f0b33a] major: Installing `drizzle-orm@rc` pulls 1.0.0-rc.5 and SQLiteSyncDialect no longer exists. [b7dc865f] minor: Selecting into a destructured tuple with `noUncheckedIndexedAccess` produces a type error on the first row. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 2 URL https://wellworn.dev/verdicts/object-storage-uploads VERDICT object storage for user file uploads in a small app PICK Cloudflare R2 2026-09: Cloudflare R2. Egress is free, storage is $0.015 per GB-month, and the free tier is 10 GB plus 1 million Class A and 10 million Class B operations a month, so a photo-heavy side project can run at zero. It speaks the S3 API, so the AWS SDK and presigned uploads work unchanged and you can leave for S3 later. ALT Amazon S3: Amazon S3 has the complete API, lifecycle rules, versioning, Object Lock, and every compliance box ticked.; wins when you need versioning, Object Lock, bucket policies, or event notifications, none of which R2 implements AVOID MinIO: MinIO. The repository was archived on 2026-04-25 with "THIS REPOSITORY IS NO LONGER MAINTAINED" at the top of the README, after the May 2025 release stripped the admin console out of the community build. Running your own S3 endpoint now means running unmaintained code. TRAPS (2) [bc86c043] major: Code that calls PutBucketVersioning, bucket policies, or S3 event notifications fails against R2. [63d9818f] major: A retried multipart upload part leaves the object corrupt or the upload unfinishable. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/mcp-sdk-typescript VERDICT which MCP server SDK and transport for a remote MCP server in TypeScript PICK MCP TypeScript SDK 1.30.0: @modelcontextprotocol/sdk 1.x with Streamable HTTP in stateless mode (`sessionIdGenerator: undefined`), one McpServer per request. It is the line every client is tested against; v2.0.0 shipped in September 2026 and splits into @modelcontextprotocol/server, /node, /express with different imports, so wait for 2.1 before moving. TRAPS (4) [876cfb42] major: Upgrading to v2 by bumping the version fails, because there is no 2.x of this package. [fb40a653] major: registerTool inputSchema written as z.object(...) is accepted by TypeScript but tools/list shows an empty schema. [0de0fa09] minor: A client written for an SSE endpoint cannot connect to a server built this year. [abab7e80] minor: The SDK imports zod/v4 internally; a project on zod 3.24 or older fails at import. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 2 URL https://wellworn.dev/verdicts/mcp-client-typescript VERDICT connecting to MCP servers from a TypeScript app or agent PICK MCP TypeScript SDK 1.30.0: The official SDK's `Client` over Streamable HTTP. On the 1.x line that is @modelcontextprotocol/sdk 1.30.0, the version every server in the wild is tested against. The 2.x line is published as a separate package, @modelcontextprotocol/client 2.0.0, implementing the 2026-07-28 spec; move when your servers do, not before, because the import paths change. ALT @modelcontextprotocol/client: mcp-use 2.4.3 wraps connection management, multi-server config, and agent glue if you are wiring several servers into one agent rather than talking to one.; wins when you connect to many servers at once and want config-file setup rather than transport objects TRAPS (4) [876cfb42] major: Upgrading to v2 by bumping the version fails, because there is no 2.x of this package. [fb40a653] major: registerTool inputSchema written as z.object(...) is accepted by TypeScript but tools/list shows an empty schema. [0de0fa09] minor: A client written for an SSE endpoint cannot connect to a server built this year. [abab7e80] minor: The SDK imports zod/v4 internally; a project on zod 3.24 or older fails at import. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/i18n-nextjs VERDICT internationalising a Next.js App Router app PICK next-intl 4.14.2: next-intl 4.14.2. It is built for the App Router specifically, so the locale reaches server components, metadata, and route handlers without a client provider wrapping the tree, and ICU message syntax covers plurals and dates. Lingui 6.6.0 is the alternative worth knowing: macros extract to PO files, the runtime is around 2 kB, and it documents React Server Component support. ALT Lingui: Paraglide JS 2.25.0 compiles messages into tree-shakable functions and reports 47 KB against 205 KB for 5 locales and 200 messages.; wins when bundle size is the constraint and your stack is SvelteKit, TanStack Start, or Astro rather than Next.js TRAPS (2) [06adbfbc] major: Messages extracted with `useExtracted` and the `po` format stop resolving after upgrading to 4.14.0. [4762ab32] minor: The `requestLocale` parameter of `getRequestConfig` is deprecated and warns. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/hosting-nextjs-own-server VERDICT Coolify vs Dokploy vs plain Docker Swarm for hosting a Next.js app on your own server PICK Coolify v4.3.18: Coolify v4.3.18 if you want a UI: Apache-2.0, 61k stars, and it drives Docker over SSH so the same install manages several servers. Plain Docker Swarm on Docker 29.8.0 if you would rather own the compose file: `docker stack deploy` plus a Caddy or Traefik service is roughly eighty lines and nothing sits between you and the daemon. Dokploy v0.30.5 is the same idea as Coolify on Swarm, with a smaller team behind it. ALT Dokploy: Dokploy runs your apps as Swarm services with Traefik in front, so scaling a service is one number in the UI.; wins when you already run Swarm and want a UI that speaks services and replicas rather than containers TRAPS (2) [8491adf9] major: Apps on a second server are unreachable because DNS still points at the main Coolify host. [c86d9718] minor: Adding a server fails at the connection step even though you can ssh in by hand. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/framework-solo-web-app VERDICT Next.js vs SvelteKit vs Astro for one person building a web app PICK Next.js 16.3.4: Next.js 16.3.4 if the app is mostly logged-in screens: server components, the largest hiring pool, and Turbopack on by default for both dev and build. Astro 7.3.1 if most pages are content and only a few islands are interactive, because it ships no JS for the rest. SvelteKit 2.70.3 is the smallest runtime of the three, but v3 is in prerelease and rewrites the adapter API, so custom adapters will need work. ALT Astro: Astro 7.3.1 renders the content pages statically and mounts React, Svelte, or Vue only where you ask for it.; wins when the app is a marketing site, docs, or blog with a small logged-in area bolted on TRAPS (2) [9e404910] major: revalidateTag('posts') stops type-checking; the single-argument form is deprecated in Next.js 16. [4155ce5b] major: A project with any webpack config fails `next build`, because Turbopack is the default bundler in 16. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/forms-validation-react VERDICT forms and validation in a React app, one schema for client and server PICK React Hook Form 7.87.0: react-hook-form 7.87.0 with zod 4.5.4 through @hookform/resolvers 5.9.1. The same zod schema validates the submitted body on the server, so a field can never be required in one place and optional in the other, and react-hook-form keeps inputs uncontrolled so typing does not re-render the form. ALT TanStack Form: TanStack Form 1.33.5 is fully type-inferred, framework-agnostic, and its field API is nicer for deeply nested and array-heavy forms.; wins when you build the same forms in React and another framework, or your forms are mostly dynamic arrays TRAPS (2) [e617db96] major: A Next.js build fails with ERR_MODULE_NOT_FOUND while resolving react-hook-form. [be44d6b1] minor: TypeScript reports excessive complexity on a large form whose values include Dayjs or Decimal. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/error-tracking-self-hosted VERDICT self-hosted error tracking that speaks the Sentry protocol PICK Bugsink 2.5.1: Bugsink 2.5.1 or GlitchTip. Both take Sentry SDK events, so you change the DSN and nothing else, and both run in a few hundred megabytes: GlitchTip documents 512 MB RAM recommended and 256 MB for the all-in-one setup. Self-hosted Sentry is the same protocol at a different scale, asking for 4 CPU cores, 16 GB RAM plus 16 GB swap, and 20 GB of disk, with no guarantees and no dedicated support. ALT GlitchTip: Sentry's hosted plan removes the operational work and gives you the full product, including performance and session replay.; wins when you need tracing and replay rather than exceptions, or you cannot spare a server at all TRAPS (0) VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/docs-site-framework VERDICT Fumadocs vs Docusaurus vs Astro Starlight for a product documentation site PICK Fumadocs 16.15.8: Fumadocs 16.15.8 if the docs live inside an existing Next.js app, because it is Next.js components rather than a separate site and you share the layout, the fonts, and the deploy. Starlight 0.42.0 if the docs are their own site: Astro ships almost no JS, and i18n, search, and the sidebar are configuration. Docusaurus 3.10.2 is the safe institutional choice with the deepest plugin and versioning story. ALT Astro Starlight: Docusaurus has documentation versioning, a large plugin ecosystem, and a translation workflow that many teams already run.; wins when you need versioned docs for several released product versions, or a translation pipeline that exists TRAPS (1) [b87876f9] minor: A `Tabs` block jumps back to the tab named in the URL hash every time you click another tab. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 5 URL https://wellworn.dev/verdicts/docs-for-coding-agents VERDICT up-to-date library documentation for a coding agent (Context7 alternatives) PICK Firecrawl Developer Index 2026-09: For plain API reference, Context7 still has the widest index (9,000+ libraries) but scores 16.8% overall on the DevDex benchmark (46.6% docs, 0.8% repos, 2.9% issue-to-fix) and cut its free tier to 1,000 calls a month in January 2026. Firecrawl's developer index (63.1%) and Mintlify's search index (54.6%) cover issues and repos too. Docfork shut down on 2026-06-14; remove it from any config. AVOID Docfork: TRAPS (0) VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/database-solo-web-app VERDICT Postgres vs SQLite or Turso vs MySQL for a solo developer's web app PICK PostgreSQL 18.6: Postgres 18.6. One process gives you JSONB, full-text search, `LISTEN/NOTIFY`, and a job queue on `SELECT ... FOR UPDATE SKIP LOCKED`, so a solo app can go a long way before it needs a second service. SQLite 3.53.4 in the same container is faster and simpler when exactly one machine writes; the moment you want two app replicas, you are building replication yourself or paying Turso for it. ALT SQLite: SQLite, embedded or through Turso, has no network hop and no connection pool. Turso's free plan is 100 databases, 5 GB, 500 million rows read and 10 million rows written per month.; wins when one machine does all the writing, or you want a separate small database per tenant AVOID MySQL: MySQL 8 is a fine database and a poor default here: you give up JSONB operators, partial and expression indexes are newer and narrower, and almost every Postgres-first tool in the TypeScript ecosystem treats it as the second target. TRAPS (1) [1163f1d7] major: Two app replicas both run migrations at boot and the second one fails on an already-applied step. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/background-jobs-postgres VERDICT background jobs for an app that already has Postgres, without adding Redis PICK pg-boss 12.30.0: pg-boss 12.30.0. Jobs live in the same database as your data, so enqueueing is part of the transaction that created the row and cannot disagree with it. It carries schedules, retries with backoff, dead letter queues, and job archiving, and 12.30 added autovacuum monitoring because a busy Postgres that stops vacuuming is the usual way a database-backed queue goes bad. ALT BullMQ: BullMQ 6.3.4 on Redis handles far higher throughput and has the better dashboard, at the cost of a second datastore that can disagree with Postgres after a crash.; wins when you push tens of thousands of jobs a minute, or you already run Redis for something else AVOID Trigger.dev: Trigger.dev 4.5.16 is a good product and a poor fit here: it is a separate orchestration platform with its own runtime and deployment story, which is a lot of moving parts for "send this email in five minutes". TRAPS (3) [404c8a9c] major: A `xmin_horizon` or `autovacuum_disabled` warning appears on the second maintenance pass after upgrading. [5f8bebc6] minor: Node logs `[PGBOSS_DEP_FETCH_SORT] DeprecationWarning` for `priority` or `orderByCreatedOn`. [1fc7377f] minor: The first boot after upgrading runs a schema migration and rebuilds the fetch index. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/auth-nextjs-solo VERDICT auth for a Next.js app, solo dev, free tier, email + Google login PICK Better Auth 1.7.3: Better Auth. You own the users table in your own Postgres, the organization and api-key plugins cover teams and keys without a second vendor, and there is no per-monthly-active-user bill when you grow. ALT Clerk: Clerk gives you hosted sign-in UI, SSO, and an admin panel in an afternoon.; wins when you need SSO or hosted UI this week and accept per-MAU pricing and a vendor-owned user store AVOID NextAuth (Auth.js): NextAuth / Auth.js v4: the v5 migration has stalled since 2025, the session callback silently drops custom fields unless typed twice, and the docs describe two incompatible APIs at once. TRAPS (2) [622e042e] major: Role or plan changes do not reach the session until the cookie cache expires (default 5 minutes). [90232128] minor: Drizzle adapter cannot find plugin tables (organization, apikey) and fails at runtime, not at build. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 3 URL https://wellworn.dev/verdicts/analytics-without-cookies VERDICT web analytics without cookies or a consent banner PICK Umami v3.3.1: Umami v3.3.1 if you want to self-host: MIT, one Node process against Postgres 12.14 or newer, and the script is under 2 KB. Plausible Community Edition is AGPLv3 and the calmer product, but it ships as a long term release twice a year and holds funnels, user journeys, ecommerce revenue goals, SSO and the Sites API back for the paid cloud. PostHog gives you far more than page views and says self-hosted deployments are officially unsupported. ALT Plausible Community Edition: Plausible Cloud or Umami Cloud costs money and removes the Postgres, upgrade, and uptime work from your plate.; wins when you would rather pay a monthly fee than own a database and a deploy for your own traffic numbers AVOID Google Analytics 4: GA4 in a project that is avoiding a consent banner. It sets identifiers and pulls you into the consent and transfer questions this whole choice exists to avoid, and the data model is events-and-parameters rather than pages. TRAPS (1) [da682065] blocker: An upgrade from Umami v2 on MySQL fails; v3 will not start against a MySQL database. VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4 URL https://wellworn.dev/verdicts/ai-sdk-typescript VERDICT Vercel AI SDK vs the provider SDK directly vs LangChain for a TypeScript app PICK Anthropic TypeScript SDK 7.0.93: Use the provider SDK directly when you call one model: @anthropic-ai/sdk 0.124.0 is a thin client over the API, so every feature lands the day it ships and nothing is translated. Reach for the AI SDK 7.0.93 when you need one interface across providers, streaming into React, or structured output with a schema. Both are reasonable; the AI SDK costs you an abstraction that lags each provider's newest options. ALT AI SDK: LangChain 1.5.10 brings retrieval, agents, and tool orchestration already assembled, at the cost of a large surface you inherit.; wins when you want prebuilt retrieval and agent graphs and accept the dependency and API churn TRAPS (0) VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4