📝

SnipDiff:コピペしたテキストを直接比較できるmacOSアプリ

に公開

はじめに

開発中に「このコードとあのコードの差分を確認したいけど、わざわざファイルに保存するのは面倒...」と感じたことはありませんか?

SnipDiffは、ファイル保存せずにコピー&ペーストしたテキストをGitHub風のUIで素早く比較できるmacOS向けデスクトップアプリケーションです。Electron + React + TypeScript + Viteで構築されており、完全にオフラインで動作します。

この記事では、SnipDiffの主要機能や技術的な特徴、実際の使い方を詳しく紹介します。

なぜSnipDiffを作ったのか

自分が欲しかったから

開発中、ファイル保存されていないテキストやコードを手軽に比較したい場面が頻繁にあります:

  • インラインに書いたYAMLやJSON設定の微妙な違いをチェック
  • メモ帳に書いた一時的なコード片の比較
  • Slackやドキュメントからコピーしたコードスニペットの確認
  • LLMの出力結果を複数回生成して比較

でも、そのたびにファイルに保存してから比較するのは正直面倒でした。

macOSには標準のFileMergeがありますが、保存済みファイルを前提としており、クリップボードの内容をサッと比較できません。VSCodeでも比較はできますが、一時ファイルを作る手間がかかります。

オンラインのテキスト比較ツールも多数存在しますが、サーバーにテキストを送信することに抵抗がありました。

「コピペしたテキストを直接比較できるツールが欲しい!」そう思って作ったのがSnipDiffです。

SnipDiffのコンセプト

  • ファイル保存不要で比較:コピペしたテキストを直接比較
  • オフライン動作:ネットワーク接続不要で完全にローカルで動作
  • GitHub風UI:開発者になじみやすいインターフェース
  • 高速起動:アプリ起動から差分表示まで1秒未満

インストール方法

Homebrew経由(推奨)

brew install shiroemons/tap/snip-diff

配布パッケージから

Releasesページから最新の.dmgファイルをダウンロードし、Applicationsフォルダにドラッグ&ドロップするだけです。

主な機能

1. リアルタイム差分表示

左右のエディタにテキストを入力すると、即座に下部の比較パネルに差分が表示されます。Monaco Editor(VS Codeと同じエディタエンジン)を搭載しているため、快適な編集体験を提供します。

2. 2つの表示モード × Compact機能 = 4パターンの差分表示

差分の表示方法を柔軟に切り替えられます。

表示モード(2種類)

Unifiedモード(⌘1)
GitHubのPR画面のような統合差分表示です。変更箇所が一目でわかります。

Unifiedモード

Side-by-sideモード(⌘2)
左右並列で詳細に比較できます。従来の2ペイン形式で、変更前後を同時に確認できます。

Side-by-sideモード

🌟 Compact機能(⌘3)— 一番のおすすめ!

どちらの表示モードでも使える、SnipDiffの目玉機能です。

通常の差分表示(Compact OFF)では、1文字だけ変更した行でも行全体に背景色が付いてしまい、「どこが変わったの?」と探すことがあります。

例えば、この設定ファイル:

database:
  host: localhost
  port: 5432    # ← ここだけ 5433 に変更
  username: admin
  timeout: 30

通常の差分表示だと、port: 5432の行全体に色が付きます。

Compactモードをオンにすると:

  • ✅ 変更された文字(23)だけが正確にハイライト
  • ✅ 共通部分(port: 543)は通常表示で見やすい
  • ✅ YAMLやJSONの微妙な違いもすぐわかる
  • ✅ スペースやタブの差異も一目瞭然

Compactモード

特に設定ファイルやインラインのYAML/JSONなど、1文字の違いが重要な場面で威力を発揮します。

つまり実質4パターン:

  • Unified + Compact OFF
  • Unified + Compact ON
  • Side-by-side + Compact OFF
  • Side-by-side + Compact ON ← 個人的に一番おすすめ!

左右で全体を見渡しながら、変更箇所だけが正確にハイライトされるので、最も差分が把握しやすいです。

  • おまけ
    Compactモード

3. シンタックスハイライト

23種類の言語をサポートしており、コードの差分を見やすく表示します。

対応言語

  • JavaScript, TypeScript, Python, Java, C#, C++, C, Go, Rust
  • PHP, Ruby, Swift, Kotlin, HTML, CSS, SCSS, JSON
  • XML, YAML, Markdown, SQL, Shell, Plain Text

4. カスタマイズ機能

テーマ

  • ライトテーマ
  • ダークテーマ
  • システムテーマ(macOSの設定に追従)

アクセントカラー

  • 青色ベース(デフォルト)
  • 緑色ベース

ボタンやチェックボックスなどのUIパーツの色を統一し、設定モーダルでリアルタイムプレビューできます。

差分オプション

  • 空白無視:空白文字の差異を無視して比較
  • 折り返し表示:長い行を折り返して表示
  • 空白文字の可視化:スペースやタブを記号で表示
    • 可視化しない / 単語境界のみ / 選択時のみ / 行末のみ / すべて可視化

改行コード指定

左右それぞれでLF/CRLF/Autoを選択可能です。Windows環境からコピーしたテキストとの比較も快適です。

5. 統計情報

比較結果の統計情報を表示します:

  • 追加行数 / 削除行数
  • Hunks数(変更ブロック数)
  • 各エディタの総行数

6. 設定の永続化

すべての設定が自動保存され、アプリ再起動後も維持されます:

  • テーマ、フォントサイズ、比較モード
  • インデント方式、改行コード、言語モード
  • 空白文字の表示設定
  • 自動更新の有効/無効

7. 自動更新機能

electron-updaterを使用した自動更新機能を実装しています。

  • 起動時チェック:設定で有効な場合、アプリ起動時に自動チェック
  • 定期チェック:12時間ごとに自動的に更新をチェック
  • 手動チェック:メニューバー > SnipDiff > 更新を確認...から実行可能
  • 更新フロー
    1. 更新チェック → 通知
    2. ダウンロード → 進捗表示
    3. ダウンロード完了 → インストール選択
    4. アプリ再起動 → 自動インストール

使い方

基本的なワークフロー

  1. テキスト入力:左側のエディタに「Before」、右側に「After」のテキストを入力
  2. 差分表示:テキストを入力すると自動的に下部の比較パネルに差分が表示
  3. モード切替⌘1 (Unified) / ⌘2 (Side-by-side) / ⌘3 (Compact)で表示を切り替え

設定の使い分け

SnipDiffでは、設定を2つの場所で管理しています:

1. フッターの設定

今の比較をカスタマイズしたい場合に使用します。

  • フォントサイズ、空白文字の表示
  • インデント方式、インデントサイズ
  • 改行コード、言語モード

フッターの設定

2. 設定モーダル(デフォルト設定)

次回起動時や新しい比較開始時の初期値を設定したい場合に使用します。

フッターの⚙ボタンから開くと、ChatGPT風の2カラムレイアウトで設定できます:
設定

  • 左サイドバー:カテゴリナビゲーション(アイコン付き)
  • 右コンテンツエリア:選択したカテゴリの設定項目

設定モーダル - 一般

設定カテゴリ

  • 一般:テーマ、アクセントカラー、自動更新
  • デフォルト設定(エディタ):フォントサイズ、インデント、改行コード、言語モード
  • デフォルト設定(差分):比較の方式、Compactモード

キーボードショートカット

ショートカット 機能
⌘, 環境設定を開く
⌘K 両側のエディタをクリア
⌘⇧K 左右のテキストを入れ替え
⌘1 Unifiedモードに切り替え
⌘2 Side-by-sideモードに切り替え
⌘3 Compactモードの切り替え

実際のユースケース

1. YAML/JSON設定の微妙な違いをチェック

インラインに書いた設定ファイルの微妙な違いを確認。ポート番号やタイムアウト値など、1文字の違いが重要な場面でCompact機能が威力を発揮します。

例:

  • GitHub Actionsのワークフローファイル
  • Docker Composeの設定
  • API設定のJSON

2. メモやドキュメントの一時的なコード片を比較

メモ帳に書いた試行錯誤中のコードや、議事録からコピーしたコードスニペットを比較。保存する前に差分を確認できます。

3. Slackやドキュメントからコピーしたコードを確認

チームメンバーがSlackに貼った修正案や、Notionに書かれた提案コードを既存コードと比較。わざわざファイルに保存せずにサッと確認できます。

4. LLMの出力結果を比較

ChatGPTやClaude Codeなどで複数回生成したコードを比較。「プロンプトをちょっと変えたらどう変わった?」を一目で確認し、どの出力が良いか判断できます。

技術スタック

SnipDiffは、Electron + React + TypeScript + Viteで構築されています。

カテゴリ 技術
フレームワーク Electron 38
UI React 19
言語 TypeScript 5
ビルドツール Vite 7
エディタ Monaco Editor
状態管理 Zustand 5
自動更新 electron-updater
テスト Vitest, Playwright
リント/フォーマット Biome
パッケージング electron-builder

開発で工夫した点

ライブラリ更新のためにテストを強化

このアプリは主にVibe Coding(Claude Codeを使った対話的開発)で実装しました。開発当初はElectron 28、React 18という構成でしたが、現在はElectron 38、React 19まで更新できています。

この大幅なアップデートを実現できたのは、テストを強化したからです。

Electronやその他の依存ライブラリは頻繁に更新されます。特にセキュリティパッチは放置できません。しかし、アップデート後に「動かなくなった」では困ります。

そこで、ライブラリを安全に更新できるようにテストを強化しました。

E2Eテストの導入

Playwrightを使ったE2Eテストを導入し、主要な機能をカバーしました:

  • アプリの起動と初期表示
  • 差分表示(3つのモード)
  • クリップボード操作
  • ファイル操作
  • 設定の保存と読み込み
  • キーボードショートカット

これにより、ライブラリをアップデートしてもテストを実行すれば動作が保証される状態になりました。

GitHub Actionsでの自動化

E2Eテストは実行時間がかかるため、すべてのコミットでは実行せず、以下の条件で自動実行されるようにしました:

  • PRにe2eラベルを追加
  • コミットメッセージに[e2e]を含める
  • リリースタグ(v*)をpush

これで、重要なタイミングでのみテストが実行され、開発速度とテスト品質のバランスが取れました。

効果

テストを強化したことで:

  • ✅ Electron 38へのメジャーアップデートも問題なく対応
  • ✅ React 19へのアップデートも安全に実施
  • ✅ 依存ライブラリのセキュリティパッチを躊躇なく適用
  • ✅ 新機能追加時の既存機能のデグレを防止

Vibe Codingで爆速実装 → テストで安全に保守という流れがうまく機能しています。

まとめ

SnipDiffは、ファイル保存せずにコピペしたテキストの差分を手軽に確認できるmacOS向けデスクトップアプリケーションです。

主な特徴

  • ファイル保存不要で直接比較
  • GitHub風のUIで開発者に馴染みやすい
  • オフライン動作でセキュリティに配慮
  • Monaco Editor搭載で快適な編集体験
  • 自動更新機能で常に最新版を利用可能

技術的な特徴

  • Electron + React + TypeScript + Viteで構築
  • セキュリティ重視の設計(contextIsolation、sandbox)
  • Zustandによるシンプルな状態管理
  • electron-updaterによる自動更新
  • PlaywrightによるE2Eテスト

「コードの差分を確認したいけど、いちいちファイルに保存するのは面倒...」という場面で、ぜひSnipDiffを試してみてください!

リンク

Discussion