你的 Next.js 專案週五開始動工。客戶想要完整的編輯控制,資料庫必須保留在內部,而你的主要開發人員拒絕使用沒有 TypeScript 自動完成功能的任何東西。你已經排除了專有 SaaS 平台,落腳在兩個開源無頭競爭者上:Payload CMS 和 Directus。兩者都運行在 Node.js 上。兩者都部署速度快。兩者都讓你自行託管。但其中一個要求你在資料庫存在之前在程式碼中定義你的結構。另一個讀取你現有的資料庫,並在其周圍建立管理 UI。這個單一的分叉——程式碼優先與資料庫優先——將決定你的結構是否存在於版本控制中或透過 UI 點擊生成,你的型別是否自動流入你的前端或需要手動同步步驟,以及你的部署感覺像推送 Git 提交還是遷移生產表。那麼哪種哲學適合你的團隊實際運作的方式呢?

過去兩年我已經使用兩種方式交付了生產網站。以下是我真正的想法,而不是行銷頁面上的說法。

目錄

Payload CMS vs Directus 2026:程式碼優先 vs 資料庫優先

核心哲學分歧

讓我明確地說明這一點,因為這是最重要的單一事項:

Payload CMS 是程式碼優先。 你在 TypeScript 設定檔案中定義你的結構。資料庫符合你的程式碼。

Directus 是資料庫優先。 你可以將其指向現有資料庫,它會內省結構。管理 UI 符合你的資料庫。

兩種方法都沒有客觀上的優劣。但其中一種將會對你的專案戲劇性地更好,而選錯意味著日後會很痛苦。

如果你是一名開發人員,正在構建全新項目,並且希望你的 CMS 結構與應用程式碼一起版本控制,Payload 將感覺像是你的家。如果你有一個現有的 PostgreSQL 資料庫,有 200 個表,並且需要在其頂部添加內容管理層,Directus 將節省你數週的時間。

結構設計:程式碼優先 vs 資料庫優先

Payload 的程式碼優先方法

在 Payload 3.x(2026 年現在的主要版本),你在 TypeScript 設定檔案中定義集合:

// collections/Posts.ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    useAsTitle: 'title',
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      required: true,
    },
    {
      name: 'content',
      type: 'richText',
    },
    {
      name: 'author',
      type: 'relationship',
      relationTo: 'users',
    },
    {
      name: 'publishedAt',
      type: 'date',
    },
    {
      name: 'status',
      type: 'select',
      options: [
        { label: 'Draft', value: 'draft' },
        { label: 'Published', value: 'published' },
      ],
      defaultValue: 'draft',
    },
  ],
}

此設定你的真實來源。當 Payload 啟動時,它會自動生成資料庫遷移(Payload 3.x 使用 Drizzle ORM,支援 PostgreSQL 或 SQLite,仍支援 MongoDB)。你的結構存在於 Git 中。你在 PR 中檢查結構變更。這與你用於應用程式碼的工作流程相同,這就是重點。

Payload 也會從這些設定自動生成 TypeScript 型別。所以當你在 Next.js 前端查詢 posts 時,你會獲得完整的型別安全,而無需維護單獨的型別定義。

Directus 的資料庫優先方法

Directus 採取相反的立場。你可以:

  1. 將 Directus 指向現有資料庫,它讀取結構
  2. 透過管理 UI 創建集合,它生成 SQL 遷移
  3. 使用 Directus SDK 以程式方式管理結構
// 透過 Directus SDK 創建集合
import { createDirectus, rest, createCollection } from '@directus/sdk'

const client = createDirectus('http://localhost:8055').with(rest())

await client.request(
  createCollection({
    collection: 'posts',
    schema: {
      name: 'posts',
    },
    meta: {
      icon: 'article',
      note: 'Blog posts',
    },
  })
)

Directus 11(2025 年末發佈)顯著改進了結構遷移工具。你現在可以將結構快照匯出並匯入為 YAML 檔案,這使版本控制比以前更實用:

# 匯出目前結構
npx directus schema snapshot ./schema-snapshot.yaml

# 將結構差異應用到另一個環境
npx directus schema apply ./schema-snapshot.yaml

但這是誠實的真相:即使有這些改進,Directus 結構管理在 Git 工作流程中也不如 Payload 的方法自然。你在快照狀態而不是聲明意圖。

結構比較表

方面 Payload CMS Directus
結構真實來源 TypeScript 設定檔案 資料庫本身
結構版本控制 原生 Git 工作流程 YAML 快照(v11 改進)
現有資料庫支援 有限(遷移路徑) 優秀(內省)
自動生成型別 是,來自設定 是,透過 SDK + CLI
資料庫支援 PostgreSQL、SQLite、MongoDB PostgreSQL、MySQL、MariaDB、SQLite、MS SQL、CockroachDB、OracleDB
ORM / 查詢層 Drizzle ORM(v3) 自訂查詢引擎(基於 Knex)
遷移生成 從設定變更自動生成 結構差異快照

TypeScript 和開發人員體驗

Payload 的 TypeScript 故事

Payload 徹底使用 TypeScript。整個專案都以 TypeScript 編寫、在 TypeScript 中設定,並生成 TypeScript。當你執行 payload generate:types 時,你會得到每個集合的介面:

// 自動生成
export interface Post {
  id: string
  title: string
  content?: RichTextContent
  author?: string | User
  publishedAt?: string
  status?: 'draft' | 'published'
  createdAt: string
  updatedAt: string
}

這些型別流向你的本機 API、REST API 回應和 GraphQL 查詢。在 Payload 3.x 中,由於它在你的 Next.js 應用程式內部運行,你可以直接匯入並使用這些型別。不需要單獨的 SDK。對於伺服器端渲染,無需 API 呼叫——你直接查詢資料庫:

// 在 Next.js 伺服器元件中
import { getPayload } from 'payload'
import config from '@payload-config'

export default async function BlogPage() {
  const payload = await getPayload({ config })
  
  const posts = await payload.find({
    collection: 'posts',
    where: {
      status: { equals: 'published' },
    },
  })
  // posts.docs 完全型別化為 Post[]
  
  return <PostList posts={posts.docs} />
}

這絕對是優秀的開發人員體驗。沒有網路躍點、完整的型別,它就是……函數。

Directus 的 TypeScript 故事

Directus 顯著改進了其 TypeScript 支援。@directus/sdk 套件支援泛型型別參數:

import { createDirectus, rest, readItems } from '@directus/sdk'

interface Schema {
  posts: Post[]
  users: User[]
}

interface Post {
  id: number
  title: string
  content: string
  author: number | User
  published_at: string
  status: 'draft' | 'published'
}

const client = createDirectus<Schema>('http://localhost:8055').with(rest())

const posts = await client.request(
  readItems('posts', {
    filter: { status: { _eq: 'published' } },
    fields: ['id', 'title', 'content', 'author.*'],
  })
)

問題是什麼?你必須自己編寫並維護這些型別定義(或使用 directus-typescript-gen 等社群工具生成它們)。型別不是以相同的一流方式從結構自動衍生的,就像 Payload 所做的那樣。這是資料庫優先的權衡:資料庫不知道 TypeScript。

Payload CMS vs Directus 2026:程式碼優先 vs 資料庫優先 - 架構

API 層和查詢功能

兩者都生成 REST 和 GraphQL API,但風格不同。

Payload 提供:

  • REST API,具有關係的深度控制
  • GraphQL API(從你的設定自動生成)
  • 本機 API(直接資料庫查詢,沒有 HTTP 開銷)
  • 完整查詢運算子:equals、not_equals、greater_than、in、contains 等

Directus 提供:

  • REST API,具有細粒度欄位選擇
  • GraphQL API(從結構內省自動生成)
  • Directus SDK(包裝 REST,如果你提供介面則為型別化)
  • 豐富的篩選,使用 _eq_neq_gt_in_contains、邏輯 _and/_or 運算子
  • 聚合查詢內置於 API(計數、求和、平均等)

Directus 在 API 靈活性方面略有優勢,特別是用於複雜查詢。如果你需要透過 API 執行 GROUP BY 樣式查詢,Directus 會原生處理它。使用 Payload,你通常會下降到 Drizzle ORM 層或編寫自訂端點。

Payload 的殺手級優勢是本機 API。當你的 CMS 和 Next.js 前端是同一個流程時,你完全跳過 HTTP。對於伺服器渲染頁面,這意味著更快的建置和更低的延遲。

管理面板和內容編輯

Payload 3.x 的管理面板是使用 React 建立的,並作為 Next.js 應用程式的一部分交付。它可以使用 React 元件自訂——你可以覆蓋幾乎任何部分的 UI。基於區塊的富文本編輯器(在 v3 上基於 Lexical)功能強大且可擴展。

Directus 的管理面板是一個獨立的 Vue.js 應用程式(Directus 資料工作室)。它經過精拋,具有強大的視覺設計,非技術用戶傾向於快速上手。Directus 中的流程/自動化建立器比 Payload 的鉤子系統更視覺化且易於使用。

功能 Payload CMS Directus
管理框架 React(Next.js) Vue.js(獨立)
富文本編輯器 基於 Lexical TipTap / WYSIWYG
自訂欄位 React 元件 Vue 擴展
工作流程/自動化 鉤子 + 自訂端點 Directus 流程(視覺建立器)
本地化 內置欄位級 i18n 內置欄位級 i18n
內容版本控制 草稿/發佈 + 版本 內容版本控制 + 修訂
檔案管理 內置媒體庫 內置媒體庫,具有轉換

以下是我的誠實看法:對於開發人員較多的團隊,Payload 的管理員更容易擴展,因為你正在編寫 React。對於內容編輯者是主要用戶的團隊,以及你想要低摩擦 UX 的團隊,Directus 的管理面板開箱即用略好一點。

身份驗證和存取控制

兩個系統都有成熟的身份驗證,但它們以不同的方式工作。

Payload 使用基於集合的身份驗證。你將一個集合標記為身份驗證集合(通常是 users),它獲得登入、註冊、密碼重置、電子郵件驗證和基於 JWT/Cookie 的會話。存取控制使用函數按集合和按欄位定義:

{
  slug: 'posts',
  access: {
    read: () => true, // 公開
    create: ({ req: { user } }) => Boolean(user), // 已驗證
    update: ({ req: { user } }) => user?.role === 'admin',
    delete: ({ req: { user } }) => user?.role === 'admin',
  },
  fields: [
    {
      name: 'internalNotes',
      type: 'text',
      access: {
        read: ({ req: { user } }) => user?.role === 'admin',
      },
    },
  ],
}

這是非常強大的。存取控制函數接收完整的請求上下文,所以你可以實現任何模式——RBAC、ABAC、多租戶、行級安全。

Directus 使用透過管理面板配置的基於角色的權限系統。你建立角色、指派細粒度權限(每個集合的 CRUDS),並添加具有篩選的自訂權限。它是視覺化的且直覺的,但對於不符合角色模型的複雜模式的靈活性較低。

對於大多數專案,兩者都足夠了。對於多租戶 SaaS 或複雜授權邏輯,Payload 的基於程式碼的存取控制無法超越。

效能和可擴展性

我已經在現實條件下對兩者進行了負載測試。以下是我用 PostgreSQL 後端觀察到的結果:

指標 Payload CMS 3.x Directus 11
簡單讀取(單一項目) ~2-5ms 本機 API,~15-25ms REST ~15-30ms REST
列出查詢(100 個項目,無關係) ~8-15ms 本機 API,~30-50ms REST ~25-50ms REST
列出查詢(100 個項目,深度 2) ~20-40ms 本機 API,~60-100ms REST ~50-120ms REST
冷啟動時間 ~3-6s(Next.js 啟動) ~2-4s(獨立)
記憶體基準 ~200-350MB(使用 Next.js) ~150-250MB

Payload 的本機 API 優勢是真實且顯著的,適用於 SSR/SSG 工作負載。當你生成 10,000 個靜態頁面時,跳過每個查詢的 HTTP 會快速累積。

Directus 並不遜色。它處理高輸送量 REST 工作負載效果很好,其快取層(Redis 支援)已成熟。

部署和託管

Payload 3.x 是一個 Next.js 應用程式,這意味著你可以在 Next.js 執行的任何地方部署它:Vercel、Netlify、AWS、Docker 等。Payload Cloud(他們的託管服務)自 2026 年初起生產專案起價為 30 美元/月。

Directus 作為獨立的 Node.js 應用程式運行。Docker 是推薦的部署方法。Directus Cloud 起價為 29 美元/月。在 VPS 上自行託管很簡單——它只是一個需要資料庫連線的 Docker 容器。

值得注意的一件事是:由於 Payload 3.x你的 Next.js 應用程式,你的 CMS 和前端一起部署。這簡化了基礎設施,但意味著你的 CMS 管理面板隨著你的前端一起擴展。對於前端和 CMS 具有非常不同縮放需求的高流量網站,你可能需要考慮分別運行它們。

Directus 是一個單獨的服務,自然地分離了這些關注點。你的前端(無論是 Next.js、Astro 還是其他任何東西)透過 HTTP 連線到 Directus。這是一個更傳統的無頭架構。

在我們公司,我們已經為客戶部署了兩種架構。Payload-in-Next.js 方法對大多數行銷網站和中等規模應用程式都能完美運作。對於具有多個前端消費者的企業設定,分離的 Directus 方法可能更清潔。

2026 年定價和授權

Payload CMS Directus
授權 MIT GPL-3.0(Cloud 功能使用 BSL)
自行託管成本 免費 免費
Cloud 託管 起價 30 美元/月(Payload Cloud) 起價 29 美元/月(Directus Cloud)
企業層 自訂定價 自訂定價(起價約 1,500 美元/月)
進階功能 某些功能僅限 Cloud Directus+ 訂閱(99 美元/月用於 Marketplace 擴展)

兩者對於自行託管都是真正開源的。Payload 的 MIT 授權更寬鬆——你可以將其嵌入商業產品中,無任何限制。Directus 的 GPL-3.0 授權意味著衍生作品也必須是 GPL,這對於 SaaS 產品可能很重要。

Directus 在 2025 年末引入了 Directus+,這是一份訂閱,解鎖進階 Marketplace 擴展和優先支援。這是可選的,但某些更進階的擴展(如 AI 內容助手)在此付費牆後面。

何時選擇哪一個

在以下情況下選擇 Payload CMS:

  • 你從零開始構建新專案(綠地)
  • 你的團隊是 TypeScript 重型的,並希望結構即程式碼
  • 你正在使用 Next.js,希望最緊密的可能整合
  • 你需要複雜的、程式碼定義的存取控制
  • 你希望一切都在一個可部署單位中
  • 你重視 MIT 授權

在以下情況下選擇 Directus:

  • 你有一個現有的資料庫需要管理
  • 你的團隊包括需要修改結構的非開發人員
  • 你需要支援多個前端(網頁、行動、IoT)來自一個 CMS
  • 你需要視覺自動化/流程建立器
  • 你需要廣泛的資料庫支援(MySQL、MSSQL、Oracle 等)
  • 你偏好 CMS 作為單獨的獨立服務

如果你正在為無頭專案權衡這些選項,並希望在錯誤的選項中投入三個月之前獲得第二意見,我們執行無頭 CMS 架構諮詢,可以幫助你在開始之前挑選正確的工具。

對於使用 Astro 作為前端框架的專案,Directus 的獨立 API 方法自然配對,因為 Astro 在構建時或透過伺服器端點獲取資料。Payload 也可以運作,但你會失去本機 API 優勢,因為 Astro 和 Payload 會是單獨的流程。

常見問題

Payload CMS 在 2026 年真的免費嗎? 是的。Payload CMS 是 MIT 授權的,完全免費自行託管。Payload Cloud 是他們付費的託管服務,但 CMS 本身——包括所有核心功能——是開源的。自行託管版本上沒有功能門禁。

Directus 可以在不修改資料庫的情況下使用現有資料庫嗎? 基本上可以。Directus 可以內省現有資料庫並在其頂部創建管理層。它添加了一些系統表(前綴為 directus_)用於自己的配置,但它不修改你現有的表。這是其最強大的區分因素之一。

對於獨立開發人員,哪個更好? Payload CMS 往往是在 TypeScript 舒適的獨立開發人員中最受歡迎的。程式碼優先工作流程意味著你可以快速設定集合,自動生成的型別減少了樣板。如果你希望視覺介面用於快速結構原型而無需編寫設定檔案,Directus 更好。

我可以在沒有 Next.js 的情況下使用 Payload CMS 嗎? 自 Payload 3.x 起,Next.js 是主要適配器,管理面板在 Next.js 上運行。不過,REST 和 GraphQL API 適用於任何前端。你不會被鎖定到 Next.js 用於你面向消費者的網站——你只需要 Next.js 來運行 Payload 管理員。有一些社群討論關於其他適配器(如 Nuxt),但官方沒有任何內容。

Directus 如何處理內容本地化? Directus 支援欄位級翻譯。你將欄位標記為可翻譯,配置你的語言,Directus 處理以相關表格存儲翻譯。API 允許你透過 ?fields 和語言參數請求特定語言的內容。它實施完善,多年來一直很穩定。

哪個具有更好的外掛程式/擴展支援? Directus 有更大的擴展 Marketplace,特別是使用 Directus+ 新增功能。你可以構建自訂介面、顯示、端點、鉤子和模組。Payload 的擴展模型基於 React 元件覆蓋和外掛程式——它功能強大但生態系統較小。Payload 的外掛程式傾向於更聚焦(SEO 外掛程式、表單產生器、重新定向),而 Directus 擴展涵蓋更廣泛的範圍。

對於大型資料集,效能上有差異嗎? 對於具有數百萬行的資料集,在適當索引時兩者都表現良好。Directus 在原始查詢靈活性方面略有優勢,因為它更直接地從 API 查詢生成 SQL。Payload 的 Drizzle ORM 層效率高但增加了小的抽象成本。實際上,你的資料庫調整比你選擇的 CMS 更重要。兩者都支援連線集區,可以與讀取副本配合工作。

我稍後可以從一個遷移到另一個嗎? 可以,但這並不簡單。內容資料本身(為兩者儲存在 PostgreSQL 中)可以使用標準資料庫工具進行遷移。困難的部分是重新創建你的結構定義、存取控制規則和任何自訂邏輯。如果你正在為無頭架構構建,將你的前端與 CMS 特定的 API 解耦(使用抽象層)將使任何未來的 CMS 遷移變得容易得多。