ヘッドレスCMS比較:Strapi vs Directus vs Payload CMS で次世代CMSを構築する
オープンソースラボ編集部 ・ 2026年6月13日
ヘッドレスCMS比較:Strapi vs Directus vs Payload CMS で次世代CMSを構築する
WordPressのようなモノリシックCMSではなく、コンテンツ管理バックエンド(API)とフロントエンド(UI)を分離したヘッドレスCMSがJAMstack・Next.js・Astroなどのモダンフロントエンド開発で採用されています。Strapi(最大シェア・Node.js)・Directus(既存DB対応・柔軟)・Payload CMS(TypeScript First・Next.js統合)の3つが2026年のOSSヘッドレスCMSデファクトスタンダードです。
ヘッドレスCMSを使う理由
- フロントエンド自由度: React/Next.js/Astro/Vue/Svelteなど好きなフレームワークでUIを構築
- マルチチャネル: 同一コンテンツをWeb・モバイルアプリ・デジタルサイネージに配信
- パフォーマンス: 静的サイト生成(SSG)と組み合わせて超高速サイトを実現
- コンテンツエディター分離: 編集者は使い慣れたCMS UIで作業→開発者は技術選定に制約なし
主要ツールの概要
Strapi
2015年公開、TypeScript製のOSSです。GitHubスター65k+。世界最大シェアのOSSヘッドレスCMSで、Content Type Builderで管理画面からスキーマを設計してREST/GraphQL APIを自動生成します。プラグインエコシステム・国際化(i18n)・ロールベースアクセス制御・カスタムAPI拡張が充実しています。
# docker-compose.yml: Strapi v5 + PostgreSQL
version: "3.8"
services:
strapi:
image: strapi/strapi:5.0
restart: unless-stopped
ports:
- "1337:1337"
environment:
DATABASE_CLIENT: postgres
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_NAME: strapi
DATABASE_USERNAME: strapi
DATABASE_PASSWORD: ${STRAPI_DB_PASS}
JWT_SECRET: ${STRAPI_JWT_SECRET}
ADMIN_JWT_SECRET: ${STRAPI_ADMIN_JWT_SECRET}
APP_KEYS: ${STRAPI_APP_KEYS}
API_TOKEN_SALT: ${STRAPI_API_TOKEN_SALT}
NODE_ENV: production
volumes:
- strapi_uploads:/opt/app/public/uploads
depends_on: [postgres]
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: strapi
POSTGRES_USER: strapi
POSTGRES_PASSWORD: ${STRAPI_DB_PASS}
volumes:
- strapi_pg:/var/lib/postgresql/data
volumes:
strapi_uploads:
strapi_pg:
// TypeScript: Strapi v5 コンテンツタイプを定義してAPIを使う
// src/api/article/content-types/article/schema.json
const articleSchema = {
kind: 'collectionType',
collectionName: 'articles',
info: { singularName: 'article', pluralName: 'articles', displayName: 'Article' },
attributes: {
title: { type: 'string', required: true },
slug: { type: 'uid', targetField: 'title' },
content: { type: 'richtext' },
cover: { type: 'media', multiple: false, required: false, allowedTypes: ['images'] },
category: { type: 'relation', relation: 'manyToOne', target: 'api::category.category' },
tags: { type: 'relation', relation: 'manyToMany', target: 'api::tag.tag' },
publishedAt: { type: 'datetime' },
seo: {
type: 'component',
repeatable: false,
component: 'shared.seo',
},
},
}
// Next.js から Strapi API を呼び出す
async function getArticles(locale: string = 'ja'): Promise<Article[]> {
const res = await fetch(
`${process.env.STRAPI_URL}/api/articles?locale=${locale}&populate=*&sort=publishedAt:desc&pagination[pageSize]=10`,
{
headers: { Authorization: `Bearer ${process.env.STRAPI_API_TOKEN}` },
next: { revalidate: 300 },
}
)
const { data } = await res.json()
return data.map((item: any) => ({
id: item.id,
title: item.attributes.title,
slug: item.attributes.slug,
content: item.attributes.content,
coverUrl: item.attributes.cover?.data?.attributes?.url,
}))
}
Directus
2012年公開、TypeScript製のOSSです。GitHubスター28k+。既存データベースをそのままREST/GraphQL APIに変換するヘッドレスCMSで、新規DB設計だけでなく「既存のPostgreSQL/MySQLテーブルをDirectusに接続して即座に管理UIとAPIを生やす」ユースケースが得意です。
# docker-compose.yml: Directus + PostgreSQL
version: "3.8"
services:
directus:
image: directus/directus:11.3
restart: unless-stopped
ports:
- "8055:8055"
environment:
SECRET: ${DIRECTUS_SECRET}
ADMIN_EMAIL: admin@example.com
ADMIN_PASSWORD: ${DIRECTUS_ADMIN_PASS}
DB_CLIENT: pg
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: directus
DB_USER: directus
DB_PASSWORD: ${DB_PASS}
WEBSOCKETS_ENABLED: "true"
CACHE_ENABLED: "true"
CACHE_STORE: redis
CACHE_REDIS: redis://redis:6379
STORAGE_LOCATIONS: local,s3
STORAGE_S3_KEY: ${S3_KEY}
STORAGE_S3_SECRET: ${S3_SECRET}
STORAGE_S3_BUCKET: ${S3_BUCKET}
STORAGE_S3_REGION: ${S3_REGION}
depends_on: [postgres, redis]
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: directus
POSTGRES_USER: directus
POSTGRES_PASSWORD: ${DB_PASS}
redis:
image: redis:7-alpine
Payload CMS
2021年公開、TypeScript製のOSSです。GitHubスター31k+。TypeScript First・Next.js統合に特化したヘッドレスCMSで、スキーマをTypeScriptで定義してAdmin UIも./payload.config.tsから自動生成し、Next.js App RouterのAPIルートとして完全統合できます。バックエンドとCMSを同一Next.jsプロジェクトに共存させる設計が特徴です。
// payload.config.ts: Payload CMS スキーマ定義(TypeScript)
import { buildConfig } from 'payload/config'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import { s3Storage } from '@payloadcms/storage-s3'
export default buildConfig({
editor: lexicalEditor(),
db: postgresAdapter({ pool: { connectionString: process.env.DATABASE_URI } }),
collections: [
{
slug: 'articles',
admin: { useAsTitle: 'title' },
fields: [
{ name: 'title', type: 'text', required: true },
{ name: 'slug', type: 'text', unique: true },
{ name: 'content', type: 'richText' },
{
name: 'cover',
type: 'upload',
relationTo: 'media',
},
{
name: 'category',
type: 'relationship',
relationTo: 'categories',
},
{
name: 'publishedAt',
type: 'date',
admin: { date: { pickerAppearance: 'dayAndTime' } },
},
],
versions: { drafts: { autosave: { interval: 2000 } } },
},
{
slug: 'media',
upload: { staticURL: '/media', staticDir: 'media', mimeTypes: ['image/*', 'video/*'] },
fields: [{ name: 'alt', type: 'text' }],
},
],
plugins: [
s3Storage({
collections: { media: true },
bucket: process.env.S3_BUCKET ?? '',
config: { credentials: { accessKeyId: process.env.S3_KEY ?? '', secretAccessKey: process.env.S3_SECRET ?? '' }, region: process.env.S3_REGION },
}),
],
secret: process.env.PAYLOAD_SECRET ?? '',
})
機能比較表
| 比較項目 | Strapi | Directus | Payload CMS |
|---|---|---|---|
| 既存DB対応 | △ | ✅ 最強 | △ |
| TypeScript First | 中 | 中 | ✅ |
| Next.js統合 | △ | △ | ✅ |
| プラグイン数 | ✅ 最多 | 中 | 中 |
| GitHub Stars | 65k+ | 28k+ | 31k+ |
ヘッドレスCMSはその他カテゴリ/categories/miscのコンテンツ管理ツールとして、Next.js App RouterのISR(増分静的再生成)・SSGと組み合わせてコンテンツがリアルタイムで配信されるWebサイトを構築します。DevOpsカテゴリ/categories/devopsのVercel・Cloudflare Pages・Netlifyへのデプロイと組み合わせてStrapiをバックエンドAPI・Next.jsをフロントエンドとする典型的なJAMstackアーキテクチャが多数採用されています。
FAQ
Q. StrapiのContent Type Builderでスキーマを設計する際のベストプラクティスは?
A. リレーションは慎重に設計・APIトークンでアクセス制御・メディアはS3にオフロードが重要です。スキーマ設計: ①コレクションタイプ(複数件)とシングルタイプ(設定・トップページ等)を適切に使い分け②リレーション: Article→Category(manyToOne)・Article→Tags(manyToMany)を設定③コンポーネント: 繰り返し使うフィールドグループ(SEO・OGP情報・CTAブロック)はコンポーネントに分離④Dynamic Zones: ランディングページのセクションをブロック単位で柔軟に構成。アクセス制御: APIトークンをContent Type別・Read-Only/Full-Accessで発行→フロントエンドはRead-Only、CI/CDデプロイはFull-Access。メディア: UPLOAD_PROVIDER=aws-s3でS3にオフロード→Strapiサーバーのディスクを使わない。
Q. Directusで既存のPostgreSQLデータベースを管理UIと化するには?
A. Directusの環境変数でPostgreSQL接続情報を設定するだけで既存テーブルを自動検出します。設定: DB_CLIENT=pg・DB_HOST=your-postgres・DB_DATABASE=existing_dbでDirectus起動→既存テーブルがCollectionsとして表示。制限事項: ①外部キー参照はリレーション設定が必要②Directusが管理用にdirectus_*テーブルを追加③既存テーブルにPrimary Key(UUID推奨)が必要。フロー(Automation): Directus内蔵のノーコードフロー機能でCRUDイベントに応じてWebhookやメール送信を自動化→Airtableライクな自動化をデータベース上で実現。LiveView(Websocket): WEBSOCKETS_ENABLED=trueでリアルタイムデータ更新をWebSocketで購読可能。
Q. Payload CMSをNext.js App Routerと同一プロジェクトに統合するには?
A. @payloadcms/nextパッケージを使って/adminルートにPayload管理UIを統合します。設定: ①npx create-payload-appでNext.js + Payload統合プロジェクトを作成②app/(payload)/admin/[[...segments]]/page.tsxにPayload管理UIが自動設置③app/(payload)/api/[...slug]/route.tsでPayload REST API(/api/articles等)が自動生成④Next.jsのRSCからimport { getPayload } from 'payload'→サーバーコンポーネントからDBを直接クエリ(APIリクエスト不要)。型安全: payload generate:typesでコレクション定義からTypeScript型を自動生成→const article: Article = await payload.findByID(...) で型付き取得。
Q. Strapi・Directus・Payload CMSのどれを選べばいいですか?
A. コンテンツエディター重視・プラグイン・最大エコシステムならStrapi、既存DB統合・nocode自動化・リアルタイムならDirectus、TypeScript・Next.js統合・開発者体験ならPayload CMSが向いています。Strapi優位: ①最大のプラグインマーケット②ビジネスユーザーが使いやすい管理UI③国際化(i18n)が成熟④Strapi Cloud(マネージドホスティング)でセルフホストなしも可。Directus優位: ①既存DBに非破壊的に接続→レガシーシステムにCMS機能を追加②ノーコードフロー自動化(Zapier代替)が内蔵③データスタジオ(データ可視化ダッシュボード)が付属。Payload CMS優位: ①コード(TypeScript)でスキーマ管理→Gitでバージョン管理②Next.js App Routerとの最深統合③Draft & Publish・バージョン履歴・ライブプレビューが標準装備。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| 最大エコシステム・コンテンツエディター重視 | Strapi |
| 既存DB統合・nocode自動化・リアルタイム | Directus |
| TypeScript・Next.js統合・開発者体験 | Payload CMS |