はじめに
Vendureは、TypeScript、NestJS、GraphQLで構築されたオープンソースのヘッドレスコマースプラットフォームですね。
GitHubで6,900スター以上を獲得しており、249名のコントリビューターが参加している活発なプロジェクトです。個人的には、カスタマイズ性の高いECサイトを構築したいなら、2025年時点でVendureは有力な選択肢だと思います。
正直なところ、最初は「ShopifyやWooCommerceでいいんじゃないか」と思っていたんですよ。でも実際にVendureを触ってみたら、なんというか「開発者のためのECプラットフォーム」という感じで、自由度の高さに驚きました。
月間20,000ダウンロード、36カ国での導入実績を持つグローバルなプロジェクトで、3,000人以上の開発者コミュニティも形成されています。
Vendureとは
Vendureは「ヘッドレスコマース」という設計思想を採用したECプラットフォームです。フロントエンドとバックエンドを完全に分離して、APIでつなぐ方式ですね。
これ、意外と重要なポイントで、従来のECシステムだとテンプレートに縛られがちだったのが、Vendureならフロントエンドを完全に自由に作れる。Next.jsでもNuxtでもSvelteKitでも、好きなフレームワークでストアフロントを構築できるわけです。
特徴・メリット
1. TypeScript + NestJSの堅牢な基盤
VendureはTypeScriptで書かれています。これ、ECサイトにとってはかなり重要で、型安全性によってバグを未然に防げる。商品データや注文データの扱いでミスが起きにくいんですよ。
NestJSベースなので、Angularに慣れている人なら学習コストも低い。DIコンテナやデコレーターを使った設計は、大規模なECシステムでも保守しやすいと思います。
2. GraphQL APIが標準装備
REST APIではなくGraphQL APIが標準。Shop API(顧客向け)とAdmin API(管理者向け)の2つが用意されています。
# 商品一覧を取得する例
query {
products(options: { take: 10 }) {
items {
id
name
slug
description
variants {
price
sku
}
featuredAsset {
preview
}
}
}
}
必要なデータだけ取得できるので、パフォーマンス的にも有利。フロントエンド開発者としては、オーバーフェッチの心配がないのはありがたいですね。
3. プラグインアーキテクチャによる拡張性
Vendureの強みは、プラグインアーキテクチャだと思うんですよ。決済、配送、在庫管理など、必要な機能をプラグインとして追加できる。
公式プラグインも充実していますし、カスタムプラグインも作れる。ビジネス要件に合わせて、コア機能を汚さずに拡張できるのはエンタープライズ向けとしてポイント高いです。
4. B2Bとマルチベンダーに対応
これ、地味にすごいなと思ったのが、B2B ECやマルチベンダー(マーケットプレイス)への対応ですね。
- 複雑な価格設定(顧客ごとの単価設定など)
- 一括注文と承認フロー
- マルチテナント構成
- ホワイトラベルソリューション
こういった要件は、SaaSのECプラットフォームだとカスタマイズが難しかったりする。Vendureなら最初から設計に含まれているので、対応しやすいです。
5. 管理画面(ダッシュボード)付き
ヘッドレスといっても、管理画面がないと運用が大変ですよね。Vendureは美しいダッシュボードが標準で付いてきます。
商品管理、注文管理、顧客管理、在庫管理など、基本的な機能は揃っている。しかもダッシュボード自体もカスタマイズ可能。自社の運用に合わせたUIに変更できます。
インストール方法
必要要件
- Node.js v20、v22、v24のいずれか
- Docker(Postgres使用時のみ)
クイックスタート
Vendureのセットアップは驚くほど簡単です。公式ツールを使えば、2分程度で動くECシステムが手に入ります。
npx @vendure/create my-shop
このコマンドを実行すると、セットアップウィザードが立ち上がります。「Quick Start」オプションを選択すると、Docker Desktopがインストールされていればpostgresデータベースが、なければSQLiteが自動で構成されます。
サーバー起動
cd my-shop
npm run dev
別のターミナルでダッシュボードを起動します。
npx vite
これで以下のエンドポイントにアクセスできるようになります。
| エンドポイント | URL |
|---|---|
| Admin API | http://localhost:3000/admin-api |
| Shop API | http://localhost:3000/shop-api |
| ダッシュボード | http://localhost:5173/dashboard/ |
デフォルトのログイン情報は、ユーザー名「superadmin」、パスワード「superadmin」です。
基本的な使い方
プロジェクト構造
生成されたプロジェクトは、こんな構造になっています。
my-shop/
├── src/
│ ├── vendure-config.ts # メインの設定ファイル
│ ├── index.ts # エントリーポイント
│ └── plugins/ # カスタムプラグイン
├── static/ # 静的ファイル
├── package.json
└── tsconfig.json
設定ファイル(vendure-config.ts)
Vendureの設定はvendure-config.tsで行います。
import {
VendureConfig,
DefaultSearchPlugin,
DefaultJobQueuePlugin,
} from '@vendure/core';
import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
export const config: VendureConfig = {
apiOptions: {
port: 3000,
adminApiPath: 'admin-api',
shopApiPath: 'shop-api',
},
authOptions: {
tokenMethod: ['bearer', 'cookie'],
superadminCredentials: {
identifier: 'superadmin',
password: 'superadmin',
},
},
dbConnectionOptions: {
type: 'postgres',
database: 'vendure',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
synchronize: true,
},
plugins: [
DefaultSearchPlugin,
DefaultJobQueuePlugin,
AdminUiPlugin,
],
};
カスタムプラグインの作成
Vendureの魅力は、プラグインで機能を拡張できること。例えば、商品にカスタムフィールドを追加するプラグインはこんな感じです。
import { VendurePlugin, PluginCommonModule } from '@vendure/core';
@VendurePlugin({
imports: [PluginCommonModule],
configuration: config => {
config.customFields.Product.push({
name: 'isLimitedEdition',
type: 'boolean',
label: [{ languageCode: 'ja', value: '限定商品' }],
defaultValue: false,
});
return config;
},
})
export class LimitedEditionPlugin {}
このプラグインをvendure-config.tsのpluginsに追加するだけで、商品に「限定商品」フラグが追加されます。
フロントエンドとの連携
Shop APIを使って、フロントエンドから商品データを取得する例です。Next.jsでの実装を想定しています。
// lib/vendure.ts
const SHOP_API_URL = 'http://localhost:3000/shop-api';
export async function getProducts() {
const query = `
query {
products(options: { take: 20 }) {
items {
id
name
slug
description
variants {
id
name
price
currencyCode
}
featuredAsset {
preview
}
}
}
}
`;
const response = await fetch(SHOP_API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const { data } = await response.json();
return data.products.items;
}
// app/products/page.tsx
import { getProducts } from '@/lib/vendure';
export default async function ProductsPage() {
const products = await getProducts();
return (
<div className="grid grid-cols-3 gap-4">
{products.map((product) => (
<div key={product.id} className="border rounded p-4">
<img src={product.featuredAsset?.preview} alt={product.name} />
<h2>{product.name}</h2>
<p>{product.variants[0]?.price} {product.variants[0]?.currencyCode}</p>
</div>
))}
</div>
);
}
実践的なユースケース
ユースケース1: D2Cブランドのオンラインストア
自社ブランドの商品を直接販売するD2Cビジネスには、Vendureがよく合います。
- ブランドの世界観を反映したカスタムフロントエンド
- サブスクリプション販売(定期購入)
- 会員限定価格の設定
- ポイントプログラムの実装
フロントエンドの自由度が高いので、ブランディングを重視するD2Cには最適ですね。
ユースケース2: B2B卸売りサイト
法人向け卸売りサイトも、Vendureの得意分野です。
- 顧客ごとの価格設定(卸価格、特別価格)
- 最小注文数量の設定
- 承認フロー(上長承認が必要な注文)
- 請求書払い対応
こういった複雑な要件は、SaaS型のECプラットフォームだと対応が難しいことが多い。Vendureならカスタムプラグインで実装できます。
ユースケース3: マルチベンダーマーケットプレイス
複数の出店者が商品を販売するマーケットプレイスも構築可能です。
- 出店者ごとの管理画面
- 売上の自動分配
- 出店者ごとの配送設定
- レビュー・評価システム
マルチテナント対応が最初から設計に含まれているので、マーケットプレイス構築のハードルはかなり下がりますね。
データベースの選択
Vendureは複数のデータベースに対応しています。
| データベース | 用途 |
|---|---|
| SQLite | 開発・テスト用。セットアップ不要で手軽 |
| PostgreSQL | 本番環境推奨。高パフォーマンス |
| MySQL / MariaDB | 既存環境との親和性が高い場合に |
本番環境では、PostgreSQLを使うのが一般的ですね。TypeORMベースなので、マイグレーションも標準的な方法で行えます。
注意点・デメリット
正直なところ、Vendureにもいくつか気になる点はあります。
学習コスト
NestJS、TypeORM、GraphQLの知識が前提になります。これらに馴染みがない場合、最初の学習コストはそれなりにかかる。ただ、どれも汎用的なスキルなので、学んでおいて損はないです。
日本語情報の少なさ
海外発のプロジェクトなので、日本語のドキュメントや記事はまだ少ない。公式ドキュメントは英語ですが、比較的わかりやすく書かれています。
ライセンス
VendureはGPLv3ライセンスです。商用利用する場合は、商用ライセンスの購入を検討する必要があるかもしれません。この辺りは公式に確認することをおすすめします。
まとめ
Vendureは、カスタマイズ性を重視するECサイト開発者にとって、かなり魅力的な選択肢だと思います。
- TypeScript + NestJS + GraphQLのモダンな技術スタック
- プラグインアーキテクチャによる高い拡張性
- B2B、マルチベンダーなど複雑な要件への対応
- 美しい管理画面が標準装備
- 活発なコミュニティと継続的な開発
「既存のECプラットフォームでは要件を満たせない」「フロントエンドを完全にコントロールしたい」という場合は、Vendureを検討してみる価値はあります。
2分でセットアップできるので、まずは触ってみて、その自由度の高さを体感してみてください。