Payload CMS vs Directus 2026:程式碼優先或資料庫優先?
你的 Next.js 專案週五開始動工。客戶想要完整的編輯控制,資料庫必須保留在內部,而你的主要開發人員拒絕使用沒有 TypeScript 自動完成功能的任何東西。你已經排除了專有 SaaS 平台,落腳在兩個開源無頭競爭者上:Payload CMS 和 Directus。兩者都運行在 Node.js 上。兩者都部署速度快。兩者都讓你自行託管。但其中一個要求你在資料庫存在之前在程式碼中定義你的結構。另一個讀取你現有的資料庫,並在其周圍建立管理 UI。這個單一的分叉——程式碼優先與資料庫優先——將決定你的結構是否存在於版本控制中或透過 UI 點擊生成,你的型別是否自動流入你的前端或需要手動同步步驟,以及你的部署感覺像推送 Git 提交還是遷移生產表。那麼哪種哲學適合你的團隊實際運作的方式呢?
過去兩年我已經使用兩種方式交付了生產網站。以下是我真正的想法,而不是行銷頁面上的說法。
目錄
- 核心哲學分歧
- 結構設計:程式碼優先 vs 資料庫優先
- TypeScript 和開發人員體驗
- API 層和查詢功能
- 管理面板和內容編輯
- 身份驗證和存取控制
- 效能和可擴展性
- 部署和託管
- 2026 年定價和授權
- 何時選擇哪一個
- 常見問題

核心哲學分歧
讓我明確地說明這一點,因為這是最重要的單一事項:
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 採取相反的立場。你可以:
- 將 Directus 指向現有資料庫,它讀取結構
- 透過管理 UI 創建集合,它生成 SQL 遷移
- 使用 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。

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 遷移變得容易得多。