オープンソースヘッドレスCMS比較:Strapi vs Directus vs Payload CMS でAPIファーストCMSをセルフホストする
オープンソースラボ編集部 ・ 2026年6月13日
オープンソースヘッドレスCMS比較:Strapi vs Directus vs Payload CMS でAPIファーストCMSをセルフホストする
WordPressの代替として「コンテンツAPIを提供するだけ」のヘッドレスCMSが主流になっています。Strapi・Directus・Payload CMSはオープンソースでセルフホストできるヘッドレスCMSです。Next.js・Nuxt・Astroなどのフロントエンドと組み合わせてコンテンツ管理システムを構築しましょう。
ヘッドレスCMSの特徴
従来のCMS(WordPress等)は「フロントエンド(テンプレート)」と「バックエンド(コンテンツ管理)」が密結合しています。ヘッドレスCMSはコンテンツをAPIで提供するだけで、フロントエンドは自由に選べます。
- REST API / GraphQL API: コンテンツをJSONで返す
- マルチチャンネル: Webサイト・モバイルアプリ・IoT等に同じコンテンツを配信
- フロントエンドの自由: React・Vue・Next.js・Astroどれでも使える
- コンテンツモデルの柔軟性: カスタムフィールドをUIで定義
主要ツールの概要
Strapi
Node.js製でGitHub Stars 65k+のオープンソースヘッドレスCMSです。コンテンツタイプビルダー・REST API・GraphQL API・ロールベースアクセス制御・マルチメディア管理を標準装備しています。
# Strapiプロジェクトの作成
npx create-strapi-app my-cms --quickstart
cd my-cms
npm run develop # ローカル起動(http://localhost:1337/admin)
# Dockerで起動
docker run -d -p 1337:1337 -v strapi_data:/opt/app/.tmp -e DATABASE_CLIENT=sqlite strapi/strapi
// Strapi v5 カスタムルートとコントローラー
// src/api/article/routes/article.ts
export default {
routes: [
{
method: "GET",
path: "/articles/featured",
handler: "article.findFeatured",
},
],
};
// src/api/article/controllers/article.ts
import { factories } from "@strapi/strapi";
export default factories.createCoreController(
"api::article.article",
({ strapi }) => ({
async findFeatured(ctx) {
const articles = await strapi.entityService.findMany(
"api::article.article",
{
filters: { featured: true },
sort: { publishedAt: "desc" },
limit: 10,
populate: ["thumbnail", "author", "categories"],
}
);
ctx.body = articles;
},
})
);
// Next.js App RouterからStrapiのAPIを呼び出す
interface Article {
id: number;
attributes: {
title: string;
content: string;
publishedAt: string;
};
}
async function getArticles(): Promise<Article[]> {
const res = await fetch(
`${process.env.STRAPI_URL}/api/articles?populate=*&sort=publishedAt:desc`,
{
headers: { Authorization: `Bearer ${process.env.STRAPI_API_TOKEN}` },
next: { revalidate: 60 },
}
);
const data = await res.json();
return data.data;
}
Directus
直感的なUIとゼロ設定のデータプラットフォームです。SQLデータベースをそのままAPIとして公開でき、既存のDBにCMS機能を後付けする「データラッパー」として使えます。TypeScriptファーストで型安全なSDKを提供します。
# Directusをdocker-composeで起動
version: '3'
services:
database:
image: postgres:16
environment:
POSTGRES_DB: directus
POSTGRES_USER: directus
POSTGRES_PASSWORD: secret
directus:
image: directus/directus:11
ports:
- 8055:8055
environment:
SECRET: your-secret-key
DB_CLIENT: pg
DB_HOST: database
DB_PORT: 5432
DB_DATABASE: directus
DB_USER: directus
DB_PASSWORD: secret
ADMIN_EMAIL: admin@example.com
ADMIN_PASSWORD: admin-password
depends_on:
- database
// Directus JavaScript SDK
import { createDirectus, rest, authentication, readItems, createItem } from "@directus/sdk";
const client = createDirectus("http://localhost:8055")
.with(authentication("json"))
.with(rest());
await client.login("admin@example.com", "admin-password");
// コレクション(テーブル)からアイテムを取得
const articles = await client.request(
readItems("articles", {
fields: ["id", "title", "content", "published_at", { author: ["name", "avatar"] }],
filter: { status: { _eq: "published" } },
sort: ["-published_at"],
limit: 10,
})
);
// 新しいアイテムを作成
const newArticle = await client.request(
createItem("articles", {
title: "新しい記事",
content: "記事の本文...",
status: "draft",
})
);
Payload CMS
TypeScript/Reactで書かれたコードファーストのヘッドレスCMSです。設定をコードで書き、TypeScriptの型安全性・React Hooksによるカスタムフィールドを活用できます。Next.jsとの統合が特に深いです。
// payload.config.ts
import { buildConfig } from "payload";
import { postgresAdapter } from "@payloadcms/db-postgres";
import { lexicalEditor } from "@payloadcms/richtext-lexical";
export default buildConfig({
secret: process.env.PAYLOAD_SECRET,
db: postgresAdapter({ pool: { connectionString: process.env.DATABASE_URL } }),
collections: [
{
slug: "articles",
admin: { useAsTitle: "title" },
fields: [
{ name: "title", type: "text", required: true },
{ name: "content", type: "richText", editor: lexicalEditor({}) },
{
name: "author",
type: "relationship",
relationTo: "users",
required: true,
},
{
name: "categories",
type: "relationship",
relationTo: "categories",
hasMany: true,
},
{ name: "publishedAt", type: "date" },
{
name: "status",
type: "select",
options: ["draft", "published"],
defaultValue: "draft",
},
],
hooks: {
beforeChange: [
async ({ data, req }) => {
if (data.status === "published" && !data.publishedAt) {
data.publishedAt = new Date().toISOString();
}
return data;
},
],
},
},
],
});
機能比較表
| 比較項目 | Strapi | Directus | Payload CMS |
|---|---|---|---|
| コンテンツタイプビルダー(GUI) | ✅ | ✅ | ❌(コード) |
| REST API | ✅ | ✅ | ✅ |
| GraphQL API | ✅ | ✅ | ✅ |
| TypeScript | ✅(v5) | ✅ | ✅ 完全 |
| 既存DB接続 | ⚠️ | ✅ | ✅ |
| Next.js統合 | ✅ | ✅ | ✅ 深い |
| ロールベースアクセス | ✅ | ✅ | ✅ |
| ファイル管理 | ✅ | ✅ | ✅ |
| マルチ言語対応(i18n) | ✅ | ✅ | ✅ |
| Webhook | ✅ | ✅ | ✅ |
| プラグイン/拡張 | ✅ | ✅ | ✅ |
| 設定のコード化 | ⚠️ | ⚠️ | ✅ |
| ライセンス | ELv2 | BUSL 1.1 | MIT |
| GitHub Stars | 65k+ | 29k+ | 30k+ |
Next.js + Payload CMSの統合例
// Next.js App Router + Payload CMS(同一Next.jsプロジェクト内)
// app/(frontend)/articles/page.tsx
import { getPayloadHMR } from "@payloadcms/next/utilities";
import configPromise from "@payload-config";
export default async function ArticlesPage() {
const payload = await getPayloadHMR({ config: configPromise });
const articles = await payload.find({
collection: "articles",
where: { status: { equals: "published" } },
sort: "-publishedAt",
depth: 2,
});
return (
<ul>
{articles.docs.map((article) => (
<li key={article.id}>
<h2>{article.title}</h2>
<p>{article.publishedAt}</p>
</li>
))}
</ul>
);
}
コンテンツ管理・ナレッジツールはknowledgeカテゴリ(/categories/knowledge)で一覧でき、ローコード・ノーコードツールはローコードカテゴリ(/categories/low-code)でも探せます。
FAQ
Q. WordPressからヘッドレスCMSに移行すべきですか?
A. WordPressで不満がなければ移行する必要はありません。ヘッドレスCMSへの移行が有効なケース: フロントエンドをReact/Vueで構築したい・1つのAPIからWebサイトとモバイルアプリに同じコンテンツを配信したい・WordPressのセキュリティ問題(xmlrpc.php・プラグインの脆弱性)を避けたい・パフォーマンス最適化(Static Site Generation)が必要な場合です。
Q. StrapiはContentfulの代替になりますか?
A. 機能的にかなり近いです。Contentfulに比べてStrapiはセルフホストでデータを管理できる点・自由なカスタマイズ・費用を大幅に抑えられる点が優れています。一方でContentfulのグローバルCDN・エンタープライズSLAが必要な場合はContentfulが適しています。
Q. Directusは「既存のDBをAPIとして公開する」とはどういう意味ですか?
A. 既存のPostgreSQL・MySQLデータベースにDirectusを接続すると、テーブルをGUI上でコンテンツとして管理・REST/GraphQL APIを通じてデータにアクセスできます。既存のアプリケーションのDBを「ヘッドレスCMS化」して管理画面を追加するユースケースに最適です。StrapiやPayloadは新規プロジェクト向けですが、Directusは既存DBへの後付けに強みがあります。
Q. Payload CMSはNext.jsと同一プロセスで動かせますか?
A. Payload CMS v3以降はNext.jsのappディレクトリ内で動作する設計になっており、同一のNext.jsプロジェクトにCMS管理画面とフロントエンドを同居させられます。next dev1コマンドでCMSとフロントエンドが同時に立ち上がり、payload.find()でDB直接アクセス(API往復なし)でコンテンツを取得できます。Vercelへのデプロイもシンプルです。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| GUIで誰でも使えるCMS | Strapi |
| 既存DBをCMS化 | Directus |
| Next.jsと深く統合したコードファーストCMS | Payload CMS |
| ContentfulからのOSS移行 | Strapi |