Swagger UIに飽きた?Stoplight ElementsでAPIドキュメントをモダンにしよう【Gin対応・他ライブラリ比較あり】
APIドキュメント、何で表示していますか?
「とりあえずSwagger UIでいいか」
「Gin使ってるし、gin-swaggerでサクッと出すか」
そんな感じで、なんとなくSwagger UIを選んでいませんか?もちろんSwagger UIは素晴らしいツールですし、機能的には申し分ないんですが、UIが少し古めかしく感じたり、StripeやTwilioのような3ペインのモダンなレイアウトに憧れたりすることはありませんか?
今回は、そんなあなたにぴったりな Stoplight Elements をご紹介します。日本語の情報がまだ少ないので、公式サイトからの引用を交えつつ、実際のUbuntu環境でのベンチマーク(重さや処理速度の比較)や、GinのSwagger UIとの比較まで、たっぷりとお届けします!
Stoplight Elementsとは?
Stoplight Elementsは、OpenAPI(旧Swagger)ドキュメントを美しく、インタラクティブに表示するためのオープンソースのUIコンポーネントです。
公式サイトでは以下のように説明されています。
"Build highly customized, interactive API Docs with embeddable web components generated from OpenAPI documents."
— Stoplight Elements 公式サイト
(意訳:OpenAPIドキュメントから生成されるWebコンポーネントを使って、高度にカスタマイズされたインタラクティブなAPIドキュメントを構築できます。)
また、GitHubのリポジトリには以下の説明があります。
"Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown."
— stoplightio/elements - GitHub
(意訳:ReactまたはWebコンポーネントとして組み込み可能な、OpenAPIとMarkdownを活用した美しくインタラクティブなAPIドキュメントを構築できます。)
最大の特徴は、StripeやTwilioのような 3カラム(3ペイン)レイアウト を簡単に実現できることです。左にナビゲーション、中央にエンドポイントの説明、右にリクエスト/レスポンスの例とTry Itパネルが配置される、あのモダンなスタイルです。
主な特徴
公式サイトでは、以下の特徴が挙げられています。[1]
| 特徴 | 説明 |
|---|---|
| Delightful developer experience | カスタマイズ可能なサイドバーと3カラムレイアウトで、開発者がAPIを素早く見つけて利用できる |
| Powered by standards | OpenAPIとJSON Schemaを活用し、動的なペイロードにも対応した美しいドキュメントを生成 |
| Interactive API console | ドキュメント内でリクエストを送信・レスポンスを確認できる「Try It」機能 |
| Code samples | cURL、Python、Ruby、Javaなど多言語のコードサンプルを自動生成 |
| Enhanced markdown support | タブ、コールアウト、JSONの埋め込みなどに対応したStoplight独自のMarkdown拡張 |
| Easy to set up | ビルドステップ不要。Webコンポーネントとして任意のフレームワークで利用可能 |
採用実績
Spotifyが開発者向けサイトの「Get Artist」ドキュメントにStoplight Elementsを採用しているほか、Dyteなど多くの企業が利用しています。[2]
実際のUIを見てみよう
まず、百聞は一見に如かず。実際のUIを見比べてみましょう。
従来のSwagger UI(gin-swagger)
GinとSwaggerの組み合わせでよく使われる swaggo/gin-swagger を使ったUIです。

エンドポイントが縦に並び、クリックするとアコーディオン形式で詳細が開きます。

機能的ですが、情報量が多くなると少し見づらくなることも。
特徴:
- シンプルな1カラムレイアウト
- アコーディオン形式でエンドポイントを展開
- 長年使われてきた安定感
Stoplight Elements
一方、Stoplight Elementsの3カラムレイアウトはこちらです。

左サイドバーでAPIの全体像を把握しながら、中央で詳細な説明を読み、右パネルでリアルタイムにAPIリクエストを試せます。

特徴:
- 3カラムレイアウト(サイドバー + 説明 + Try It)
- レスポンスのスキーマが見やすく整理されている
- コードサンプルが多言語で自動生成される
- OpenAPI 3.1対応
他パッケージとの比較(実測ベンチマーク)
「他にもRedocやScalarがあるじゃないか」と思うかもしれません。そこで、実際のUbuntu環境(Node.js v22.13.0)で、代表的なAPIドキュメントUIライブラリのインストールサイズとバンドルサイズを実測してみました。
比較対象パッケージ
| パッケージ名 | バージョン | 特徴 |
|---|---|---|
| @stoplight/elements | v9.0.16 | 今回の主役。3カラムレイアウト対応 |
| swagger-ui-dist | v5.32.2 | Swagger UI公式。最も普及している |
| redoc | v2.5.2 | シンプルで軽量。2カラムレイアウト |
| @scalar/api-reference | v1.51.0 | 新興。モダンなデザイン |
1. インストールサイズ(node_modulesの重さ)
プロジェクトに組み込む際の重さ(依存関係を含む)です。以下はUbuntu上で npm install した際の実測値です。
# 計測コマンド
du -sh node_modules
| パッケージ名 | node_modulesサイズ(実測) |
|---|---|
| redoc | 82 MB |
| @stoplight/elements | 125 MB |
| swagger-ui-dist | 190 MB |
| @scalar/api-reference | 481 MB |
Redocが最も軽量です。Stoplight Elementsは125MBと中程度、Scalarは依存関係が非常に多く481MBとかなり重めです。
2. バンドルサイズ(ブラウザに配信されるファイルサイズ)
実際にブラウザで読み込まれる際のファイルサイズ(Minify済みのJS/CSS)です。Ubuntu上で実測しました。
# ファイルサイズの計測
ls -lh <bundle-file>
# gzip後サイズの計測
gzip -c <bundle-file> | wc -c
| パッケージ名 | JSサイズ (Minified) | gzip後 | CSSサイズ |
|---|---|---|---|
| redoc (standalone.js) | 919 KB | 281 KB | (JSに内包) |
| swagger-ui-dist (bundle.js) | 1.5 MB | 403 KB | 175 KB |
| @stoplight/elements (web-components.min.js) | 2.0 MB | 583 KB | 291 KB |
| @scalar/api-reference (standalone.js) | 3.8 MB | 1.08 MB | (JSに内包) |
Stoplight Elementsは、ReactベースのWebコンポーネントとして提供されているため、Swagger UIやRedocと比べるとバンドルサイズはやや大きめです。ただし、gzip後は583KBと、昨今のネットワーク環境であれば十分に許容範囲内です。CDNを使えばキャッシュも効くので、実際の体感速度はそれほど気になりません。
3. 機能比較
| 機能 | Stoplight Elements | Swagger UI | Redoc | Scalar |
|---|---|---|---|---|
| 3カラムレイアウト | ✅ | ❌ | ✅ | ✅ |
| Try It(APIリクエスト送信) | ✅ | ✅ | ❌(有料版のみ) | ✅ |
| OpenAPI 3.1対応 | ✅ | ✅ | ✅ | ✅ |
| Webコンポーネント対応 | ✅ | ❌ | ❌ | ❌ |
| Markdown記事サポート | ✅(Dev Portal) | ❌ | ❌ | ❌ |
| 多言語コードサンプル | ✅ | ✅ | ❌ | ✅ |
| ライセンス | Apache 2.0 | Apache 2.0 | MIT | MIT |
GinのSwagger UIからStoplight Elementsへ移行する
ここからは、実際にGinで作ったAPIにStoplight Elementsを組み込む方法を解説します。
現状のGin + gin-swaggerの構成
Ginを使っている場合、swaggo/gin-swagger を使ってSwagger UIを表示するのが定番です。
# swagコマンドのインストール
go install github.com/swaggo/swag/cmd/swag@latest
# gin-swaggerのインストール
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
// main.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
_ "yourproject/docs" // swagで生成したdocsを読み込む
)
// @title Sample API
// @version 1.0
// @description This is a sample server.
// @host localhost:8080
// @BasePath /api/v1
// PingExample godoc
// @Summary ping example
// @Description do ping
// @Tags example
// @Produce json
// @Success 200 {string} string "helloworld"
// @Router /example/helloworld [get]
func Helloworld(c *gin.Context) {
c.JSON(http.StatusOK, "helloworld")
}
func main() {
r := gin.Default()
// Swagger UIのルートを追加
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run(":8080")
}
# swagコマンドでOpenAPIドキュメントを生成
swag init
# サーバー起動後、以下のURLでSwagger UIにアクセス
# http://localhost:8080/swagger/index.html
これで http://localhost:8080/swagger/index.html にアクセスすると、おなじみのSwagger UIが表示されます。
Stoplight Elementsを組み込む方法
Stoplight Elementsを使う場合、OpenAPIドキュメント(JSONまたはYAML)さえあれば、HTMLファイルを1つ追加するだけで完了です。
方法1: HTMLファイルを追加する(最も簡単)
// main.go に追加
r.GET("/docs", func(c *gin.Context) {
c.Data(200, "text/html; charset=utf-8", []byte(stoplightHTML))
})
// OpenAPIのJSONを提供するエンドポイント(swaggoが生成したものを使う)
r.GET("/docs/openapi.json", func(c *gin.Context) {
c.File("./docs/swagger.json")
})
// HTMLテンプレート(定数として定義)
const stoplightHTML = `<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>API Documentation</title>
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>html, body { height: 100%; margin: 0; }</style>
</head>
<body>
<elements-api
apiDescriptionUrl="/docs/openapi.json"
router="hash"
layout="sidebar"
/>
</body>
</html>`
これだけです!http://localhost:8080/docs にアクセスすると、Stoplight ElementsのモダンなUIでAPIドキュメントが表示されます。
方法2: 静的ファイルとして配置する
# staticディレクトリを作成
mkdir -p static/docs
<!-- static/docs/index.html -->
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>API Documentation</title>
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>html, body { height: 100%; margin: 0; }</style>
</head>
<body>
<elements-api
apiDescriptionUrl="/docs/openapi.json"
router="hash"
layout="sidebar"
/>
</body>
</html>
// main.go
r.Static("/docs", "./static/docs")
r.GET("/docs/openapi.json", func(c *gin.Context) {
c.File("./docs/swagger.json")
})
方法3: npmパッケージとして使う(Reactプロジェクト)
Reactを使っている場合は、コンポーネントとして組み込めます。
npm install @stoplight/elements
import { API } from '@stoplight/elements';
import '@stoplight/elements/styles.min.css';
const ApiDocs = () => (
<div style={{ height: '100vh' }}>
<API
apiDescriptionUrl="/docs/openapi.json"
router="hash"
layout="sidebar"
/>
</div>
);
設定項目(プロパティ)完全まとめ
<elements-api> タグ(または <API> コンポーネント)に渡せる全設定項目です。[3]
基本設定
| プロパティ名 | 型 | 説明 | デフォルト値 |
|---|---|---|---|
apiDescriptionUrl |
string | OpenAPIドキュメント(JSON/YAML)のURL。http://・https://・$refを含むドキュメントに対応 |
(必須) |
apiDescriptionDocument |
string/object | OpenAPIドキュメントの文字列またはオブジェクトを直接渡す場合に使用 | — |
basePath |
string |
router: 'history' 使用時に、ドキュメントがサブディレクトリにある場合のベースパス(例:/docs/api) |
— |
レイアウト設定
| プロパティ名 | 型 | 説明 | デフォルト値 |
|---|---|---|---|
layout |
string | レイアウトの指定。3種類から選択 | sidebar |
logo |
string | サイドバー上部に表示するロゴ画像のURL | — |
layout の選択肢は以下の3つです。
公式ドキュメントには次のように記載されています。[3:1]
sidebar— (default) Three-column design with a sidebar that can be resized.responsive— Like sidebar, except at small screen sizes it collapses the sidebar into a drawer that can be toggled open.stacked— Everything in a single column, making integrations with existing websites that have their own sidebar or other columns already.
-
sidebar(デフォルト): 3カラムデザイン。サイドバーのサイズ変更が可能 -
responsive:sidebarと同様だが、小さい画面ではサイドバーがドロワーに切り替わる -
stacked: 1カラム。既存のサイドバーを持つCMSへの組み込みに最適
ルーター設定
| プロパティ名 | 型 | 説明 | デフォルト値 |
|---|---|---|---|
router |
string | ナビゲーションの方式 | history |
router の選択肢は以下の4つです。
history— (default) uses the HTML5 history API to keep the UI in sync with the URL.hash— uses the hash portion of the URL to keep the UI in sync with the URL.memory— keeps the history of your "URL" in memory (doesn't read or write to the address bar).static— renders using the StaticRouter which can help render pages on the server.
-
history(デフォルト): HTML5 History APIを使用。通常のURLでナビゲーション -
hash: URLのハッシュ部分を使用。SPAや静的サイトに向いている -
memory: URLを変更せずにメモリ内でナビゲーション -
static: StaticRouterを使用。サーバーサイドレンダリング(SSR)に対応
表示制御
| プロパティ名 | 型 | 説明 | デフォルト値 |
|---|---|---|---|
hideInternal |
boolean |
x-internal でマークされたコンテンツを非表示にする |
false |
hideTryIt |
boolean | 「Try It」機能を完全に非表示にする | false |
hideTryItPanel |
boolean | Try Itパネルを非表示にしつつ、リクエストサンプルは表示する(hideTryIt: false が前提) |
false |
hideSchemas |
boolean |
sidebar レイアウト使用時に、目次からスキーマを非表示にする |
false |
hideExport |
boolean | ドキュメント概要セクションの「Export」ボタンを非表示にする | false |
Try It設定
| プロパティ名 | 型 | 説明 | デフォルト値 |
|---|---|---|---|
tryItCorsProxy |
string | Try It機能でリクエストを送信する際に使用するCORSプロキシのURL | — |
tryItCredentialsPolicy |
string | Try It機能のクレデンシャルポリシー。omit(デフォルト)、include、same-origin から選択 |
omit |
コマンドまとめ
インストール
# npm
npm install @stoplight/elements
# yarn
yarn add @stoplight/elements
# pnpm
pnpm add @stoplight/elements
CDNで使う(ビルド不要)
<!-- JSの読み込み -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<!-- CSSの読み込み -->
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
バージョンを固定して使う(推奨)
<!-- バージョンを固定する場合(例:v9.0.16) -->
<script src="https://unpkg.com/@stoplight/elements@9.0.16/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements@9.0.16/styles.min.css">
Ginプロジェクトでのswag操作
# swagコマンドのインストール
go install github.com/swaggo/swag/cmd/swag@latest
# OpenAPIドキュメントの生成(プロジェクトルートで実行)
swag init
# 特定のファイルを指定して生成
swag init -g main.go --output docs
# ネストしたディレクトリ構成の場合
swag init -g ./cmd/yourapp/main.go -o cmd/docs
# 生成されるファイル
# docs/
# ├── docs.go # Goのソースコード
# ├── swagger.json # OpenAPI JSON
# └── swagger.yaml # OpenAPI YAML
Gin + Stoplight Elementsの完全なサンプルコード
以下は、GinでAPIを作りつつ、Stoplight Elementsでドキュメントを表示する完全なサンプルです。
// main.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
_ "yourproject/docs"
)
// @title Sample API
// @version 1.0
// @description Stoplight Elements デモ用APIサーバー
// @host localhost:8080
// @BasePath /api/v1
// User ユーザー情報
type User struct {
ID int `json:"id" example:"1"`
Name string `json:"name" example:"John Doe"`
Email string `json:"email" example:"john@example.com"`
}
// GetUsers ユーザー一覧を取得
// @Summary List all users
// @Description Get a list of all users in the system
// @Tags users
// @Produce json
// @Success 200 {array} User
// @Failure 500 {object} map[string]string
// @Router /users [get]
func GetUsers(c *gin.Context) {
users := []User{
{ID: 1, Name: "John Doe", Email: "john@example.com"},
}
c.JSON(http.StatusOK, users)
}
const stoplightHTML = `<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>API Docs</title>
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>html, body { height: 100%; margin: 0; }</style>
</head>
<body>
<elements-api
apiDescriptionUrl="/openapi.json"
router="hash"
layout="sidebar"
/>
</body>
</html>`
func main() {
r := gin.Default()
// APIルート
v1 := r.Group("/api/v1")
{
v1.GET("/users", GetUsers)
}
// OpenAPI JSONを提供
r.GET("/openapi.json", func(c *gin.Context) {
c.File("./docs/swagger.json")
})
// Stoplight Elements UIを提供
r.GET("/docs", func(c *gin.Context) {
c.Data(200, "text/html; charset=utf-8", []byte(stoplightHTML))
})
r.Run(":8080")
}
# ドキュメント生成 & サーバー起動
swag init && go run main.go
# アクセス
# APIドキュメント: http://localhost:8080/docs
# OpenAPI JSON: http://localhost:8080/openapi.json
Swagger UIとの使い分け
では、Swagger UIとStoplight Elements、どちらを使えばいいのでしょうか?
| ユースケース | 推奨 |
|---|---|
| 社内ツール・開発中のAPI確認 | Swagger UI(手軽さ優先) |
| 外部公開のAPIドキュメント | Stoplight Elements(見た目・UX優先) |
| 既存のCMSやサイトに埋め込む | Stoplight Elements(stackedレイアウト) |
| Markdownドキュメントと組み合わせる | Stoplight Elements Dev Portal |
| 最小限の依存関係で使いたい | Redoc |
| バンドルサイズを最小にしたい | Redoc |
Swagger UIは「とにかく動かしたい」というときに最適です。一方、Stoplight Elementsは「外部の開発者に使ってもらうAPIドキュメントを作りたい」「見た目にこだわりたい」という場合に特に力を発揮します。
まとめ
Stoplight Elementsのポイントをまとめると:
- 導入は超簡単 — HTMLに2行追加するだけ(CDN利用)
- 見た目が圧倒的にモダン — 3カラムレイアウトで情報が整理されている
- Try It機能が充実 — ドキュメント内でAPIリクエストを送信できる
-
Gin + swaggoとの相性も良好 — 既存の
swagger.jsonをそのまま使える - バンドルサイズはやや大きめ — 2.0MB(gzip後は約583KB)
- node_modulesは125MB — Redocの82MBより大きいが、Scalarの481MBよりは軽量
「APIドキュメントのUIをちょっとリッチにしたいな」と思ったら、ぜひStoplight Elementsを試してみてください!既存のSwagger UIから移行するのも、HTMLを1ファイル追加するだけなので、本当に簡単です。
参考リンク
- Stoplight Elements 公式サイト
- stoplightio/elements - GitHub
- Elements Configuration Options - 公式ドキュメント
- swaggo/gin-swagger - GitHub
- swaggo/swag - GitHub
Discussion