· auth / nextjs / authjs

Auth.js vs Clerk — tự xây hay dùng hosted auth cho Next.js

Auth.js lưu users trong database của bạn, miễn phí ở mọi quy mô. Clerk tính ~$17,225/tháng ở 1M users nhưng setup chỉ 15 phút. Phân kỳ ở 50k MRU.

Bởi Ethan

2.164 từ · 11 phút đọc

Auth.js lưu users trong database của bạn và miễn phí dù đạt một triệu users. Clerk tính khoảng $17,225 mỗi tháng ở quy mô đó. Đổi lại: Clerk mất 15 phút để cài đặt, đi kèm UI components dựng sẵn, và có official support cho Astro. Auth.js mất ít nhất một tiếng, không có UI đi kèm, và v5 vẫn đang ở giai đoạn beta.

Dưới 50k monthly active users, Clerk miễn phí và giúp bạn ship nhanh hơn. Vượt ngưỡng đó, Auth.js bắt đầu là lựa chọn bền vững hơn. Yêu cầu về data sovereignty hoặc các quy định compliance nghiêm ngặt sẽ đẩy nhanh quyết định đó.

Bài này dành cho ai

Dành cho developer đang chọn giải pháp auth cho Next.js App Router và muốn có câu trả lời rõ ràng. Nếu bạn dùng Astro, các phân tích này vẫn áp dụng được — phần Astro ở cuối bài là dành riêng cho stack đó.

Những gì chúng tôi thử nghiệm

Auth.js [email protected] so với @clerk/nextjs (v6.x), cả hai trên Next.js App Router. Nguồn tham khảo là tài liệu chính thức của cả hai thư viện. Không có con số benchmark nào được bịa ra — chỗ nào cần đo bằng công cụ thực sự, chúng tôi nói thẳng.

Kết quả

Chi phí cài đặt

Clerk thắng ở mục này rõ ràng.

Cài đặt Auth.js (một OAuth provider, không dùng DB adapter):

  1. npm install next-auth@beta
  2. npx auth secret — tạo biến môi trường AUTH_SECRET bắt buộc
  3. Tạo auth.ts ở thư mục gốc của project: NextAuth({ providers: [] })
  4. Thêm route handler tại app/api/auth/[...nextauth]/route.ts
  5. Thêm middleware tùy chọn trong middleware.ts
  6. Cấu hình client ID và secret riêng cho từng OAuth provider

Thời gian thực tế: 30–60 phút cho một OAuth provider hoạt động được. Thêm DB adapter, callbacks, và quyết định session strategy, bạn sẽ mất 1–2 tiếng.

Cài đặt Clerk:

  1. npm install @clerk/nextjs
  2. Thiết lập NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEY — hoặc bỏ qua cả hai với Keyless Mode, tự tạo credentials tạm thời để bạn không cần tài khoản Clerk khi bắt đầu
  3. Thêm clerkMiddleware() vào middleware.ts
  4. Bọc root layout với <ClerkProvider>

Thời gian thực tế: 5–15 phút để có trang login hoạt động. Keyless Mode cho phép bạn kiểm tra integration hoạt động trước khi cần tạo tài khoản Clerk.

Khoảng cách này mang tính cấu trúc, không phải do tài liệu kém. Auth.js là thư viện bạn cấu hình; Clerk là sản phẩm bạn kết nối vào.

Providers được hỗ trợ

Auth.js: Hơn 130 OAuth provider được cấu hình sẵn. GitHub, Google, Apple, Discord, Twitter, Microsoft Entra ID, Okta, Salesforce, Notion, Stripe, LinkedIn, Spotify, và hơn một trăm cái khác. Email magic links qua Resend, SendGrid, và NodeMailer. Xác thực bằng credential (mật khẩu) được hỗ trợ nhưng tài liệu chính thức không khuyến khích dùng.

Passkeys: Đang thử nghiệm. Auth.js bổ sung hỗ trợ WebAuthn từ beta.17, kích hoạt qua flag experimental: { enableWebAuthn: true }. Tài liệu nói thẳng rằng tính năng này chưa dùng được trên production. Ngoài ra bạn cần DB adapter, migration thêm bảng Authenticator, và cả @simplewebauthn/browser + @simplewebauthn/server làm peer dependencies.

SAML: Không có sẵn. Bạn có thể dùng Okta hoặc Azure AD làm OAuth provider để thay thế. Cách đó chạy được, nhưng bạn phải tự lắp ráp.

Clerk: Google, GitHub, Facebook, và hơn 20 social provider khác (số chính xác không được liệt kê công khai; bạn thấy đầy đủ trên Clerk dashboard khi đăng ký). Email OTP và magic links. SMS OTP qua điện thoại. Xác thực qua Web3 wallet — MetaMask, Coinbase Wallet, Base, OKX.

Passkeys: Sẵn sàng cho production trên gói Pro. Không cần flag experimental, không cần cài thêm peer dependencies.

SAML/Enterprise SSO: Có sẵn. Azure AD, Google Workspace, Okta, và bất kỳ IdP nào tuân thủ SAML — hỗ trợ cả SP-initiated và IdP-initiated flows (SAML chỉ cho IdP-initiated). Dùng được trong môi trường development trên gói miễn phí (tối đa 25 connections) và trong production trên gói Pro.

Nếu enterprise SSO nằm trong roadmap của bạn trong sáu tháng tới, con đường Auth.js đòi hỏi bạn tự xây hạ tầng. Nếu độ rộng OAuth provider quan trọng — hơn 130 so với hơn 20 — Auth.js thắng ở tiêu chí đó.

Quyền sở hữu dữ liệu

Đây là điểm khác biệt quan trọng nhất với các workload chịu sự điều tiết.

Auth.js lưu mọi thứ trong database của bạn. Bạn chọn adapter: Prisma, Drizzle ORM, MongoDB, Firebase, Neon, Supabase, Vercel Postgres, và nhiều cái khác. Mặc định không có user data nào rời khỏi hạ tầng của bạn. Nếu bạn đang cân nhắc giữa Prisma và Drizzle cho adapter, bài so sánh Prisma vs Drizzle phân tích chi tiết từng lựa chọn. Session là JWT (stateless, không cần DB roundtrip, giới hạn ~4KB, không thể thu hồi trước khi hết hạn nếu không có blocklist) hoặc database-backed (stateful, có thể thu hồi, cần adapter, thêm một DB roundtrip mỗi request).

Clerk lưu user store trên cloud của Clerk. Bạn có thể sync dữ liệu về database của mình qua webhooks. Clerk đạt chứng nhận SOC 2 (từ gói Business trở lên). Tuân thủ HIPAA yêu cầu gói Enterprise kèm BAA. Clerk không cung cấp lưu trữ dữ liệu theo khu vực — thay vào đó tuân thủ quy tắc chuyển dữ liệu EU qua EU–US Data Privacy Framework.

Với workload nhạy cảm về GDPR, healthcare, EU fintech, hoặc bất kỳ trường hợp nào mà “user records trên SaaS của bên thứ ba” là điều không thể chấp nhận, Auth.js là lựa chọn khả thi duy nhất. Với team muốn có compliance được quản lý sẵn mà không cần tự xây hạ tầng bảo mật, các chứng nhận của Clerk có giá trị thực sự.

Giá cả

Auth.js miễn phí. Giấy phép MIT. Bạn chỉ trả tiền cho nhà cung cấp database và email.

Clerk miễn phí đến 50.000 Monthly Retained Users (MRU). MRU tính những user quay lại hơn 24 tiếng sau khi đăng ký — user đăng ký ngày đầu không tính (grace period “First Day Free”). Ngoài ra còn có grace period một tháng trước khi bắt đầu tính phí overage.

Users (MRU)Auth.jsClerk (Pro, $25/tháng cơ bản, tính theo tháng)
10k$0$25/tháng (trong gói miễn phí)
100k$0~$1,025/tháng
1M$0~$17,225/tháng

Mức phí overage giảm dần theo quy mô: $0.020/MRU từ 50k–100k, $0.018 từ 100k–1M, $0.015 từ 1M–10M.

Gói miễn phí 50k đủ rộng cho hầu hết sản phẩm giai đoạn đầu. Đường cong chi phí sau ngưỡng đó đủ dốc để các team dự tính scale lớn phải tính đến trước khi bị ràng buộc.

DX: TypeScript, middleware, và câu hỏi về beta

Auth.js được typed đầy đủ bằng TypeScript, dùng module augmentation để mở rộng các kiểu Session, User, Account, và JWT ở cấp global. Mô hình callback — callbacks.jwt, callbacks.session, callbacks.signIn — dài dòng nhưng rõ ràng. Khi đã hiểu cấu trúc, nó trở nên dễ dự đoán.

Điểm khó chịu là pattern tách cấu hình cho edge runtime. Core của Auth.js v5 xây dựng trên standard Web APIs và tương thích với edge. DB adapters thì không — TCP socket connections không thể chạy ở edge. Giải pháp:

  • Một auth.ts không có DB adapter dùng trong middleware.ts — chạy ở edge với JWT sessions
  • Một auth.ts có DB adapter cho API routes — chạy trong Node.js runtime với database sessions

Cách này đúng về mặt kiến trúc, nhưng không hiển nhiên và là điểm vấp ngã lặp đi lặp lại với developer đến từ v4 hoặc mới làm quen với edge deployments. Tài liệu có đề cập, nhưng bạn cần biết phải tìm ở đâu.

Câu hỏi lớn hơn là tính ổn định. [email protected] là bản phát hành npm hiện tại. v4 ổn định là 4.24.14. v5 đang được deploy trên production ở hàng nghìn ứng dụng và là phiên bản mà toàn bộ tài liệu hiện tại hướng đến — nhưng nó có breaking changes từ v4 và chưa có ngày phát hành stable chính thức. Nếu team bạn có chính sách không dùng thư viện pre-stable, hãy lưu ý điều này.

Clerk cung cấp SDK ổn định, sẵn sàng cho production. auth() cho server components, useAuth() cho client hooks, clerkMiddleware() để bảo vệ route với pattern matching đơn giản. TypeScript đầy đủ. Keyless Mode xóa bỏ mọi rào cản khi chạy lần đầu. Không có gì trong cài đặt Clerk đòi hỏi bạn phải hiểu về edge runtime.

UI components

Auth.js không đi kèm bất kỳ UI nào. Form đăng nhập, trạng thái lỗi, loading skeleton, nút đăng nhập mạng xã hội — bạn phải tự xây tất cả. Đó là ít nhất một ngày làm việc cho một flow hoàn chỉnh; nhiều hơn nếu bạn cần xây MFA entry, org switching, hoặc xử lý magic link hết hạn.

Clerk đi kèm <SignIn />, <SignUp />, <UserButton />, <UserProfile />, và <OrganizationSwitcher /> là các component có thể dùng ngay. Bạn tùy chỉnh màu sắc, logo, và routing behavior từ Clerk Dashboard mà không cần chỉnh code. Chúng hoạt động ngay từ đầu khi render lần đầu.

Một điều cần lưu ý: gói miễn phí (Hobby) hiển thị badge “Secured by Clerk” trên các component. Muốn xóa badge đó cần nâng lên gói Pro.

Hỗ trợ Astro

Với dự án Astro — stack mà toolchew đang dùng — so sánh này có câu trả lời rõ ràng ngay hôm nay.

Auth.js không có official Astro adapter. Có một pull request đang mở nhưng chưa được merge. Tài liệu Auth.js liệt kê Astro dưới mục “Community integrations” — tức là không có official support, không có bảo đảm về bảo trì, và bạn tự chịu trách nhiệm khi có gì đổ vỡ.

Clerk có package @clerk/astro chính thức với quickstart đầy đủ. Yêu cầu SSR mode (output: "server" trong astro.config.mjs, dùng adapter @astrojs/node — không hỗ trợ static site export). Cả năm component đều hoạt động trong Astro. Keyless Mode cũng dùng được.

Nếu bạn đang dùng Astro và cần auth ngay bây giờ, Clerk là lựa chọn duy nhất có official support cấp production. Nếu bạn chưa quyết định giữa Astro và Next.js, xem Next.js vs Astro để so sánh đầy đủ hai framework.

Kết luận

Chọn Auth.js nếu:

  • Bạn dự tính vượt 50k MRU và không thể chấp nhận chi phí overage của Clerk khi scale lên
  • Data sovereignty là yêu cầu bắt buộc — GDPR, healthcare, EU fintech, hoặc bất kỳ trường hợp nào không thể để user records trên SaaS của bên thứ ba
  • Bạn cần hơn 130 OAuth provider và provider cụ thể của bạn không có trong danh sách của Clerk
  • Bạn không ngại tự xây auth UI và quản lý DB adapter

Chọn Clerk nếu:

  • Bạn cần ship auth trong một buổi chiều
  • Bạn đang xây trên Astro và muốn official support
  • Enterprise SSO hoặc SAML nằm trong roadmap và bạn không muốn tự xây hạ tầng
  • Bạn muốn có UI components dựng sẵn, tùy chỉnh được
  • Passkeys trên production quan trọng với bạn ngay bây giờ chứ không phải sau này

Điểm phân kỳ nằm quanh 50k MRU. Dưới ngưỡng đó, Clerk miễn phí và nhanh hơn ở mọi khía cạnh quan trọng cho giai đoạn đầu. Vượt qua đó, chênh lệch chi phí và đánh đổi data ownership bắt đầu bù đắp cho chi phí cài đặt của Auth.js và việc thiếu UI layer.

Lưu ý

Auth.js v5 vẫn đang ở giai đoạn beta. Nó đang được dùng trên production, nhưng vẫn là thư viện pre-stable. Nếu tổ chức bạn yêu cầu phiên bản stable, hãy dùng Auth.js v4 (4.24.14) — với lưu ý rằng v4 đang ở maintenance mode và tài liệu đã chuyển sang v5 — hoặc dùng Clerk.

Không có benchmark công khai nào so sánh Auth.js và Clerk về request latency hay throughput. Cả hai đều đủ nhanh để latency liên quan đến auth không phải yếu tố quyết định với workload web thông thường. Chúng tôi không bịa số liệu.

Số lượng social provider chính xác của Clerk không được tài liệu hóa công khai. “Hơn 20” dựa trên cách diễn đạt của tài liệu. Nếu một provider ít phổ biến cụ thể là yêu cầu bắt buộc, hãy kiểm tra trên Clerk dashboard trước khi quyết định.

Tham khảo

  1. Auth.js Getting Started
  2. Auth.js Installation (Next.js)
  3. Auth.js Provider List
  4. Auth.js Session Strategies
  5. Auth.js Passkeys/WebAuthn
  6. Auth.js Edge Compatibility
  7. Auth.js TypeScript Guide
  8. Auth.js Framework Integrations
  9. Auth.js GitHub
  10. Clerk Pricing
  11. Clerk Next.js Quickstart
  12. Clerk Astro Quickstart
  13. Clerk Enterprise SSO/SAML