Storybook風SlackApp UIのプレビューツール『slack-blockbook』を作ってみた!

LayerX Tech Advent Calendar 2025の11日目の記事です。
バクラク事業部 でバクラク勤怠を作っているソフトウェアエンジニアの @tiger です。
今日はSlack Block KitのStorybook風プレビューツール slack-blockbook を作成したので紹介させてください!
想定読者
- SlackAppを開発している(または興味がある)エンジニア
- jsx-slackを使っている開発者
前提:私たちの技術スタック
私が属している勤怠チームでは、SlackAppを @slack/bolt と jsx-slack を利用して開発しています。
@slack/boltは、Slack公式のJavaScript/TypeScriptフレームワークです。イベントのリスニング、メッセージ送信、モーダル表示など、SlackApp開発に必要な機能が一通り揃っています。
jsx-slackは、Slack Block Kit JSONをJSXで記述できるライブラリです。Reactライクな書き心地でSlack UIを構築できるため、フロントエンド開発者にとって馴染みやすいのが特徴です。
// jsx-slackを使うと、Block Kit UIをJSXで直感的に書ける
<Blocks>
<Section>
<b>Hello!</b> This is a <i>jsx-slack</i> example.
</Section>
<Actions>
<Button actionId="click">Click me</Button>
</Actions>
</Blocks>

このコードから生成されたJSONをSlack Block Kit Builderでのプレビューしたもの
これらの素晴らしいライブラリを開発・メンテナンスしてくださっているSlack公式チームとyhattさんに感謝します🙏
SlackApp開発の「つらみ」
SlackAppを開発したことがある方なら、一度はこんな経験をしたことがあるのではないでしょうか。
「ちょっとUIを確認したいだけなのに、なぜこんなに大変なんだ...」
また ホーム画面、アラート通知、承認ワークフローモーダルなど、Block Kit UIコンポーネントは日々増え続け、気づけば条件分岐が複雑に絡み合うコンポーネントが増えてきました。そんな中で感じていた「つらみ」を具体的に挙げてみます。
つらみ1:実際のSlackで確認するには手間がかかる
普段の開発では、UIの確認は実際のSlackワークスペースで行っています。しかし、これがなかなか手間がかかる。
まず、SlackでUIを確認するためだけに必要なサービスを立ち上げる必要があります。ローカル開発サーバーを起動して、Slackと連携できる状態にしないとBlock Kit UIの確認すらできない。
さらに厄介なのが通知やメッセージのUI確認。ホーム画面ならSlackアプリを開けば見られますが、通知メッセージの見た目を確認したい場合は実際にSlackに送信するしかありません。そして送信するためには、その通知をトリガーするためのデータを用意する必要がある。
「残業アラートの見た目を確認したい」→ 残業データを作成 → 通知を送信 → 確認 → 「テキスト変えたい」→ コード修正 → また送信...
UIをちょっと確認したいだけなのに、テストデータの準備から始めないといけないのがつらい。
つらみ2:Block Kit Builderのプレビューを使うにしてもコピペ地獄
「じゃあ簡易的に Block Kit Builder で確認すればいいじゃん」と思うかもしれません。しかし、これもなかなかつらい。手順としては以下の流れです。
- コードでBlock Kit JSONを生成
-
console.logなどで出力してコピー - Block Kit Builder を開いてペースト
- 見た目を確認
- 修正してまた1に戻る...
この「コード → コピペ → 確認 → 修正」の無限ループ。UIの微調整をするたびに、この作業を繰り返すのはしんどいです。
つらみ3:条件分岐UIの組み合わせが多岐わたるパターン
実際のUIには条件分岐がつきもの。例えば「管理者かどうかでボタンの表示を変える」といったケース
<Actions>
<Button actionId="view">詳細を見る</Button>
{isAdmin && <Button actionId="edit">編集する</Button>}
</Actions>
この isAdmin = true のパターンと false のパターン、両方確認したい。でも、そのためにはコードを書き換えるか、実際のSlackで管理者アカウントと一般アカウントで試すしかない...。
さらに複雑なのが、複数の条件が組み合わさるケース
function NotificationMessage({ user, alerts, settings }) {
return (
<Blocks>
{alerts.hasOvertime && <Section>⚠️ 残業アラート</Section>}
{alerts.hasMissingPunch && <Section>🕐 打刻漏れがあります</Section>}
{settings.showSummary && <Section>📊 今月のサマリー...</Section>}
{user.isAdmin && <Actions>...</Actions>}
</Blocks>
);
}
リグレッションテスト等でこれらのすべての組み合わせを毎回確認するのは現実的には辛い作業になります。
これらの「つらみ」を解消したい。もっと手軽に、もっと素早くBlock Kit UIを確認できる方法はないものか...。
Storybookからの着想
そんなとき、ふと思い出したのがフロントエンド開発で愛用しているStorybookの存在でした。
Storybookは、Reactなどのコンポーネントをアプリケーション全体を起動せずに単体でプレビュー・開発できるツールです。私たちのチームでもWebアプリのUI開発で日常的に使っています。
考えてみると、Storybookが解決している課題と、Block Kit開発の「つらみ」は驚くほど似ていました
| 課題 | Reactコンポーネント開発 | Slack Block Kit開発 |
|---|---|---|
| UI確認に手間がかかる | アプリ全体を起動しないと確認できない | Slackと連携したサーバーを起動しないと確認できない |
| 条件分岐のテストが面倒 | 状態を手動で切り替えて確認 | 実際のSlackで該当データを用意して確認 |
| コンポーネントの一覧がない | コードを読まないと全体像がわからない | 同上 |
「これ、Block Kitでもできるんじゃないか?」
そうして作ってみたのが @layerx/slack-blockbook です。
slack-blockbook
slack-blockbook の主な特徴:
- ゼロコンフィグで
npx slack-blockbook blockbook.tsを実行するだけで即起動 - ファイル保存で即座にプレビューが更新されるホットリロード機能
- args/argTypesで動的にUIを切り替えられるインタラクティブなコントロール
- ワンクリックでBlock Kit BuilderのURLを生成
- jsx-slackに対応しており、JSXでもJSON直書き可能
使い方
npm install @layerx/slack-blockbook
設定ファイルを作成し、CLI コマンド一発でサーバーが起動します。
// blockbook.ts
import { startBlockKitPreviewServer } from " @layerx/slack-blockbook";
startBlockKitPreviewServer({
port: 5176,
workspaceId: "YOUR_SLACK_WORKSPACE_ID",
searchDir: import.meta.dirname,
projectName: "my-slack-app",
restartOnChange: true,
watchPatterns: ["**/*.tsx"],
});
npx @layerx/slack-blockbook blockbook.ts
これだけで.blockkit.tsxファイルを自動検出してプレビューサーバーが立ち上がります。ファイルを編集して保存すれば、ブラウザが自動でリロードされるホットリロード付きです。
Hello World:最小のBlockbook
Storybook ユーザーなら「あ、この書き方知ってる」と感じるはずです。
// hello.blockkit.tsx
import { createStory } from " @layerx/slack-blockbook";
import { Blocks, Section } from "jsx-slack";
export const stories = [
createStory({
name: "Hello World",
description: "シンプルなHello Worldメッセージ",
tags: ["basic"],
component: () => (
<Blocks>
<Section>Hello, World! 👋</Section>
</Blocks>
),
}),
];

Hello Worldの例
createStory, args, argTypesといった概念を Storybook からそのまま採用しました。jsx-slack でも JSON 直書きでも、どちらでも動きます。
コントロールパネルで条件分岐を確認
冒頭で挙げた「条件分岐 UI の確認が面倒」という課題。slack-blockbook ではargsとargTypesを定義するだけで、コントロールパネルから動的に値を切り替えられます。
// notification.blockkit.tsx
import { Actions, Blocks, Button, Header, Section } from "jsx-slack";
import { createStory } from " @layerx/slack-blockbook";
interface NotificationArgs {
title: string;
message: string;
type: string;
showButton: boolean;
}
const typeEmojis: Record<string, string> = {
info: "ℹ️",
success: "✅",
warning: "⚠️",
error: "❌",
};
const NotificationBlock = (args: NotificationArgs) => (
<Blocks>
<Header>
{typeEmojis[args.type] || ""} {args.title}
</Header>
<Section>{args.message}</Section>
{args.showButton && (
<Actions>
<Button actionId="view_details">View Details</Button>
</Actions>
)}
</Blocks>
);
export const stories = [
createStory<NotificationArgs>({
name: "Notification/Message",
description: "さまざまなタイプの通知メッセージ",
args: {
title: "Notice",
message: "You have a new message.",
type: "info",
showButton: true,
},
argTypes: {
title: { control: "text", description: "通知タイトル" },
message: { control: "text", description: "通知内容" },
type: {
control: "select",
options: ["info", "success", "warning", "error"],
description: "通知タイプ",
},
showButton: { control: "boolean", description: "ボタン表示" },
},
component: (args) => NotificationBlock(args),
}),
];

コントロールパネルで条件分岐を確認
コントロールの種類はtext, number, boolean, select, dateとStorybook でお馴染みのものを揃えました。例ではshowButtonのチェックボックスをポチポチするだけでボタンありなし両方の UI を即座に確認できます。
また、Block Kit Builderで実際のSlackのUIコンポーネントを使用したプレビューにもすぐに遷移して確認することができます。
exampleに幾つか例を載せているので参考にしてみてください。
まとめ
slack-blockbook は、「開発者体験を改善するツールは、既存の優れたツールから学ぶ」という考えから作成してみました。Storybook という素晴らしいツールのコンセプトを借りることで、Slack Block Kit 開発の体験を改善する助けになると嬉しいです。
| 項目 | Before | After |
|---|---|---|
| UI 確認の所要時間 | 5〜10 分 | 数秒 |
| 必要な準備 | Bot トークン、Webhook、ngrok 等 | なし |
| 変更の反映 | アプリ再起動 | 自動リロード |
| 条件分岐の確認 | コード書き換え or 実データ準備 | コントロールパネルで即切替 |
| コンポーネント一覧 | コードを読む | サイドバーで一覧表示 |
同じ悩みを持つ SlackApp 開発者の方々の助けになれば幸いです。ぜひ使ってみてください!!
Discussion