RubyKaigi 2026に参加してきました

RubyKaigi2026

はじめに

プロダクト開発部プラットフォームエンジニアリンググループの小椋です。

4月22日〜24日に北海道函館市で開催された RubyKaigi 2026 に参加してきました。 コアサービスであるOfferBoxはPHPをメイン言語としていますが、部分的にRubyを採用しているところや、AI時代に言語設計者がどういう考えで開発をするのかという興味もあり、言語処理系やエコシステムの動向をキャッチアップする目的で参加できました。

今回は3日間を通して印象に残ったセッションをピックアップして紹介します。振り返ってみると、JITやコンパイラ周りのセッションを多く聞いており、最終日のMatzキーノートで発表されたAOTコンパイラ「Spinel」に向けて伏線が回収されていくような体験になりました。

  • はじめに
  • Day 1
    • The Journey of Box Building / tagomoris
    • Rapid Start: Faster Internet Connections, with Ruby's Help / kazuho
    • The design and implementation of ZJIT / Max Bernstein
  • Day 2
    • Surviving Black Friday: 100 billion requests with Falcon! / ioquatix 他
    • From Formal Specification to Property Based Test / ohbarye
  • Day 3
    • (Re)make Regexp in Ruby / makenowjust
    • Matz Keynote / matz
  • 会場の様子
  • おわりに
続きを読む

「迷ったらYES」が現場を加速させる。職種の壁を溶かし、一体感を生む「オンサイト×密連携」の力(後編)

目次

  • 目次
  • 前回(サービス・プロダクト編)の振り返り
  • レポート②:組織・カルチャー編
    • ① 【意思決定】合言葉としての「迷ったらYES」
      • 自社で取り入れるとしたら
    • ② 【職域の融合】エンジニアとビジネスサイドの「ゼロ距離」連携
      • 「阿吽の呼吸」を生むリアルなコミュニケーション
      • リモートと出社の強みと課題
      • フルリモート下で「ゼロ距離」をどう再現するか
    • ③ 【当事者意識】複数サービスを越境した貢献
      • i-plugのエンジニア体制
      • 「越境」をさらに進めるために
  • イベントのまとめと今後の展望
    • 最後に

前回(サービス・プロダクト編)の振り返り

前編では、求人おきなわ様の「多角的な面展開」と、それを支える技術スタック刷新への決断力についてレポートしました。 両社のアプローチの違いである「地域を面で押さえる多角展開」と「学生の時間軸に沿った垂直特化」が、エンジニアに求められるスキルや視点の違いとして現れることが印象的でした。 こうした戦略的な開発を支えているのは、どのようなエンジニア組織なのか。後編では、私たちが沖縄の地で肌で感じた「組織・カルチャー」にフォーカスします。

kyujinokinawa.co.jp

続きを読む

「沖縄最大級の多角展開」vs「新卒特化のプラットフォーム」。戦略の違いが生む「開発スタイル」の対比(前編)

目次

  • 目次
  • はじめに:技術交流会の背景
  • イベント当日の様子(ダイジェスト)
  • レポート①:サービス・プロダクト編
    • ①【戦略比較】沖縄を「面」で押さえる多角展開と学生生活を「線」で支える垂直特化
      • 求人おきなわ:地域に根ざした多角展開
      • i-plug:若手人材の成長を時系列で深掘り
    • ② 【タッチポイント】SEO・オープン設計と生活・行動にフォーカスした接点
    • ③ 【開発思想】レガシーと決別する「一新する勇気」
  • 前編のまとめ
    • 両社の特性比較:それぞれの強みと組織文化
    • i-plugの「スケールする力」と課題の再認識
    • 学びと今後の指針

はじめに:技術交流会の背景

先日、沖縄の株式会社求人おきなわ様を訪問し、技術交流会を行ってきました。 きっかけは、「同じHR領域にいても、異なる歴史や背景を持つチームと対話することで、新しい視座を得たい」という好奇心です。 この呼びかけに快く応えてくださったのが、沖縄の求人メディアを牽引する求人おきなわの皆さんでした。 同じ業界で切磋琢磨しているとはいえ、開発スタイルやプロダクトの裏側はそれぞれに異なります。 普段自分たちが「当たり前」だと思い込んでいる手法を一度フラットに疑ってみて、より良いものづくりのヒントを得ることが今回の目的です。 具体的にどんな議論が交わされたのか、振り返ってみたいと思います。

kyujinokinawa.co.jp

イベント当日の様子(ダイジェスト)

交流会は、那覇市にある求人おきなわ様の本社にお邪魔して開催。プログラムは「会社紹介」「プロダクトハンズオン」「トークセッション」の3部構成です。 冒頭の会社紹介では、今回のために作成された会社説明資料が紹介されました。その資料の作成にGensparkやNotebookLMを活用しており、そのスピード感と新しいツールを即座に現場へ取り入れる遊び心に、会場が引き込まれたのが印象的でした。 私たちi-plugからも、会社紹介やプロダクト(OfferBox)の概要についてお話しさせていただきました。

続くハンズオンでは、お互いのプロダクトを実際にスマホで触りながらのディスカッション。 「この導線、意図は何ですか?」「この表示条件、裏側はどう制御してるの?」といった、エンジニア特有の実装の背景や設計意図を追求する質問が飛び交う濃い時間になりました。

続きを読む

ESLint+PrettierからOxlint+Oxfmt移行の理想と現実 ~pre-commitが20秒から5秒になるまで~

はじめに

フロントエンド領域で開発を行っている赤星です。

弊社はcommit時にgitのpre-commitフックによりESLint+Prettier+tscを走らせ、フォーマット+コードチェックを行っていたのですが、最近これをESLint+Oxlint+Oxfmt+tsgoの構成に変更を行いました。

しかし、移行にあたり、様々な障害にぶつかって詰まったので「理想と現実」「その乗り越え方」をここで紹介します。

プロダクトのESLint+Prettierが重くOxlint+Oxfmtに移行しようと検討されている方の一助になればと思います。

目次

結論

結論から言います。大変ですが移行してよかったです。「理想と現実」というタイトルをつけている以上「やめとけ」みたいな文脈にも見えてしまうので、あらかじめ断っておきます。事実commitをする度に20秒待たされていたのが5秒で終わるようになっています。4倍速くなったということです。これは大きな開発生産性の向上であり、移行して非常によかったと感じています。

Oxlint+Oxfmtのすごいところ(理想)

圧倒的な速さ

私がOxlintというツールを知った時非常に驚いたのはその圧倒的な速さです。Oxlintと同じRust製であるBiomeのLint機能はESLintの10倍以上高速と言われています。しかしOxlintはそのBiomeより2倍速いそうです。

ESLintやESLintプラグインの高い互換性

さらにOxlintはESLintのメジャーなプラグイン(eslint-plugin-reacteslint-plugin-jsx-a11ytypescript-eslint等)とも高い互換性があり(対応プラグイン一覧)、Oxlintの内部プラグインとしてRustで移植されています。さらにOxlintに移植されていないプラグインも外部プラグインとして実行できる仕組みが用意されています。(参考)

そしてESLintはコメントでのルール制御をする際、例えば

// eslint-disable-next-line react/no-array-index-key

と書くと思いますが、Oxlintは

// oxlint-disable-next-line react/no-array-index-key

と書きます。eslintの部分がoxlintになっただけであり、これは非常にとっつきやすいです。

移行コマンドの存在

Oxlint+Oxfmtを開発しているVoidZeroはoxlint-migrateというESLintからの移行コマンドを用意しています。flat-configで書かれたESLintのみの対応ですが、これにより、

npx @oxlint/migrate eslint.config.js --type-aware

とコマンドを叩くだけで既存のESLint設定を元に.oxlintrc.jsonを生成してくれます。

ESLint併用機能

Oxlintはまだまだ開発中です。既存のESLintルールやプラグインの中でまだ対応されていないルールもちらほらあります。(対応 or 非対応一覧はこのissueから確認可能)

そのためOxlintはESLintとの併用機能が用意されており、eslint-plugin-oxlintというESLintの拡張機能が用意されています。

これを既存のESLintに導入すると、ESLintで定義されているルールのうち、Oxlintで実装済みのルールをスキップすることができます。

移行奮闘記 ~ぶち当たった現実~

ESLintと何も考えずに併用すると思ったより速くならない

Oxlintを導入する前、ESLintの全体走査は約40秒程度かかっていました。試しに移行コマンドを行い、eslint-plugin-oxlintを導入した後、ワクワクしながらどれくらい短くなったのかとESLint+Oxlint併用での全体走査をしました。果たして何秒になったでしょうか。

なんと約30秒です🫠

速くなったと言われれば速くなりましたが、大して速くなりませんでした...

調査してみたところtypescript-eslintプラグイン(ESLint側)に大きな落とし穴がありました。

ESLintのtypescript-eslintプラグインは名前の通りTypeScript向けのESLintプラグインですが、TypeScriptにおける型情報のルール違反検知を実現するために、内部でTypeScriptのコンパイラエンジンを利用しており、ローカルのtsconfig.jsonを参考に動作します。これが非常に重く実行時間の増加の原因となっていました。Oxlintのtypescript-eslintプラグインはこれを回避するために内部にtsgoを利用したtsgolintを利用しているのですが、Oxlintはtypescript-eslintプラグインを全て移行しきれている訳ではないので、ESLint側のtypescript-eslintが動作し、結果的に実行時間を上げていました。

弊社OfferBoxの環境ではESLint側で残っていたtypescript-eslint系は

  • typescript-eslint/no-throw-literal
  • typescript-eslint/dot-notation

だけであり、それぞれOxlintに別名で実装済み / 近い将来正式実装される ことがわかったので、思い切って削除をすることでこの問題を解決しました。

結果的に全体走査にかかる時間を約20秒まで縮めることに成功しました。(本当はもっと速くしたいんですがね...)

Oxlintの仕様をある程度は理解しないといけない

「何も考えずにESLintからコマンド1発置き換え🎵」みたいなのは少し厳しいです。単純なESLint設定ファイルならまだしも、問題はeslint-config-airbnbのような設定パッケージを利用していたり、あるいは単純に複雑なESLint設定を書いている場合です。

分かりやすい例としてno-throw-literalというルールがあります。これは簡単に言うと「throwを書くときはErrorオブジェクトを利用してね」というルールなのですが、Oxlintでは非推奨となっています(参考)。代わりに似たルールであるtypescript/only-throw-errorを使うことが推奨されているのですが、これを利用するにはOxlintの設定に手動で書き込まなくてはいけません。

もう一点分かりやすい例としてはESLintのreact-hooksプラグインです。Oxlintはreact-hooksプラグインを完全移行済みなのですが、このプラグインはルールが2つしかないこともあり、reactプラグインに統一されています(該当issue)。なので、これを知らないと生成された.oxlintrc.jsonを見て「あれ...?react-hooksプラグインが見当たらないぞ...?」となります。(ちなみにこちらは移行コマンド実行時にreact/exhaustive-deps: "error"のようにreactプラグインに変換されているので特別な対応は必要ありません)

後は

  • Oxlintにtypescript-eslintをしっかり見てもらうには--type-awareオプションをつける必要がある (参考)

等細かい仕様の違いがあります。

Oxlintの未発見バグに3種類当たった(Oxlint最新版で修正済み)

Oxlintへの変換コマンドを実行したのち、試しに実行してみたところ、ESLintとの差分(ESLintの時は検出されなかったのがOxlintでルール違反として検出される、あるいはその反対)が発生しました。

最初は最新のESLintのバージョンを利用していなかったのが原因なのかなと考えていたのですが、Oxlintに指摘された(あるいは指摘されなかった)コードをみたところどうやらOxlintのバグであることが分かりました。

実際に当たったバグはそれぞれ以下であり、issueに報告しました。

github.com

※keyの値をテンプレートリテラル等で加工した場合、配列のindexをkeyに利用していてもreact/no-array-index-keyが引っかからない

github.com

※imgタグのaltにhelloImageのようにImageという単語が使われているが前の単語とスペースなしでくっついている場合の時、jsx-a11y/img-redundant-altの誤検知が発生する

github.com

※ asを利用して「型」としてuseEffectの外にある変数が利用されている場合、react/exhaustive-depsの誤検知が発生する

Oxlint側の対応がされるまでの一時的な対応策として、誤検知が引っかからないようなコードに書き直したり、// oxlint-disable-next-line-***を書くことで対応しました。 やはり新しいOSSということもあり、仕方ないのですが、特定条件の時バグにちらほら遭遇した印象です。

その他

上記全てを対応したところ、pre-commitは10秒程度になりました。個人的にはまだ速くしたいと思って調べてみたところ、tscもどうやら重そうということが分かり、ここの記事の本題から逸れるので詳細は書きませんが、tsgoを導入し、tsc --noEmitからtsgo --noEmitにすることでさらに5秒短縮に成功しました。

まとめ

Oxlint+Oxfmtの仕様を調べるためにGitHubのissueを探したりリファレンス漁ったり非常に大変でした...

しかし、前述したようにpre-commitの時間がかなり短縮され、開発体験を上げることに成功したので、やった甲斐はあったなと感じています。 さらに、新しいOSSということもあって積極的に開発が行われており、実際私が上記に挙げたreact/no-array-index-keyのバグはissueを出してから1時間以内に対応され、mainブランチにマージされていました(すごい)。ESLintルール移植もどんどんされており、今後が非常に楽しみなツールです。

いつかESLintを完全廃止できたらいいなぁと思いつつこの記事を締めたいなと思います。

PHPerKaigi 2026にシルバースポンサーとして参加してきました

PHPerKaigi2026のロゴが映った写真

はじめに

先日開催されました、PHPerKaigi2026に、i-plugはシルバースポンサーとして協賛しております。

phperkaigi.jp

今年も、参加した社員のレポートとして、印象に残ったセッションを紹介していきます。

  • はじめに
  • 印象に残ったセッション
    • モジュラモノリス導入から4年間の総括:アーキテクチャと組織の相互作用について
    • キーワードは「延命」 ― リプレイス困難システムの現実的バージョンアップ戦略
    • 「お金で解決」が全てではない!大規模WebアプリのCI高速化
    • Laravel Nightwatchの裏側 ― Laravel公式Observabilityツールを支える設計と実装
    • PHPでできる!自作IPルーター
    • AIと共に「使うOSS」から「育てるOSS」へ
    • 存在論的プログラミング: 時間と存在を記述する
    • php-srcの話が多かった印象がある
    • 見せてもらおうか、OpenSearchの性能とやらを!
    • Ruby VM 開発者がZend VMのopcodeを眺めてみた
    • Feature Toggle は捨てやすく使おう
  • 最後に
続きを読む

Claude Code × Playwright MCPでローカルの動作確認からバグ発見まで任せてみた話

Claude Code × Playwright MCPでローカルの動作確認からバグ発見まで任せてみた話

  • Claude Code × Playwright MCPでローカルの動作確認からバグ発見まで任せてみた話
    • はじめに
    • Claude Code × Playwright MCP とは
      • Claude Code
      • Playwright MCP
    • セットアップ
    • 実践:テンプレート切り替え機能の動作テスト
      • テスト対象の概要
      • テストシナリオの設計
      • Claude Codeに渡したプロンプト
      • テスト実行で使われた手法
        • 1. browser_snapshot でページ構造を把握
        • 2. browser_click でモーダル・ラジオボタン・送信を操作
        • 3. browser_evaluate でhidden inputの排他制御を検証
        • 4. docker compose exec でDB検証・データリセット
      • テスト結果
    • テスト中にバグを発見した話
      • 異変の報告
      • browser_evaluateでDOM調査
      • 原因特定:JSファイルのパス不整合
      • 修正→再テストで解決
    • 使ってみて感じたこと
      • よかった点
      • 注意点
    • まとめ
続きを読む

React Tokyo 2026 参加レポート

React Tokyo 2026参加レポート

プラットフォームチームの三品です。 2/28に開催されたReact Tokyoに参加しましたので、その参加レポートになります。

React Tokyo 2026

きっかけ

オライリーの「Reactハンズオンラーニング」を読みました。 書籍ではuseStateやuseEffectといったHooksの設計思想が「なぜこうなっているのか」という視点で書かれており、普段バックエンドを中心に開発している自分にとって新鮮でした。「この理解を深めるには実際にReactコミュニティの人たちと話すのが一番だろう」と思い、React Tokyoへの参加を決めました。

ポスターセッションがメイン

ポスターセッションとは、会場にReactに関するポスターが展示され、参加者とポスターの投稿者同士でディスカッションするスタイルです。

通常の登壇形式のカンファレンスだと聞く側に回りがちですが、ポスターセッションは興味のあるトピックを選んで投稿者に直接質問できるので、自分のペースで参加できるのが良かったです。ポスターはReactの基礎的な内容から上級者向けの内容まで幅広くカバーされていました。

開発現場で使って難しいと感じたNext.js

Next.jsが難しいと感じたことを投稿されていました。具体的には

  • もともとLaravelを使ったフルスタックの開発をしており、React/Next.jsの基礎知識が不足した状態で使い始めたため難しいと感じた。
  • ReactでわからないのかNext.jsでわからないのか曖昧になっている。
  • キャッシュ周りが複雑。

であることを挙げていました。

私自身も思い通りの挙動にならなかったときに、その原因がReactなのかNext.jsの問題なのか分からなかったことや、キャッシュ周りの問題でAPIでPOSTされたデータが画面側で反映されずに苦労したことがある ので、投稿者のけいすけさんと話が盛り上がりました。

特にキャッシュについては、Next.jsのApp Routerで導入されたfetch単位のキャッシュやRouter Cacheなど、複数のレイヤーにキャッシュが存在しており、どのキャッシュが効いているのか切り分けるのが大変だったという点で意見が一致しました。自分としてはバックエンドエンジニアとしてLaravelのキャッシュの方が明示的で扱いやすいと感じる一方、フロントエンドはユーザー体験を追求するために複雑なキャッシュ戦略が必要になるのだなと改めて実感しました。

また、けいすけさんからuseMemo()はパフォーマンスの最適化をしてくれるが、React Compilerを導入すると、コンパイラ側で最適化してくれることを教えてもらいました。 つまり、開発者がuseMemo()やuseCallback()を手動で書く必要がなくなり、メモ化の判断をコンパイラに任せられるようになるとのことでした。これはDX(開発体験)の大きな改善になりそうだと感じました。

目で見てサッと理解する!Reactの思想と内部実装入門

Reactの内部で使われているFiberアーキテクチャと、レンダリングが「トリガー → スケジューリング → レンダー → コミット」という4つのフェーズで処理される仕組みが図解でわかりやすくまとめられていました。Reactの内部実装まで意識することはなかなかないので、こうした仕組みを知ることで「なぜReactはこういう挙動をするのか」がより理解しやすくなると感じました。

RSCの仕組みをNext.jsとTanstack Startの比較から理解したい

RSC(React Server Components)の仕組みを両フレームワークの視点から紐解いてわかりやすく解説されていました。

Tanstack Startについては知らなかったのですが、ざっくり言うとTanStack Router(クライアントサイドのルーティングライブラリ)をベースにしたフルスタックフレームワークで、Next.jsのようにSSRや サーバーサイドの機能を提供しつつも、クライアントサイドのルーティングを軸にしている点が特徴的だと解説されていて、勉強になりました。

投稿者のIORIさんからお話を聞いて、Tanstack Startでは、Composite Componentという'use client'を開発者が意識しなくてもよくなるコンポーネントの仕組みが開発中とのことで、DXが変わると思うのでリリースされることをとても楽しみにしています。

まとめ

普段はバックエンド側の開発がメインである私でも、本イベントはポスターセッションで気軽に話しかけられるようになっており、とても楽しめました。

今回の参加を通して、React Compilerによるメモ化の自動化やTanstack StartのComposite Componentなど、「開発者が意識しなければならないことを減らす」方向にフロントエンドのエコシステムが進化していることを感じました。バックエンドエンジニアとしても、こうしたフロントエンドの動向をキャッチアップしておくことで、チーム内での技術的な議論やアーキテクチャの意思決定に貢献できると思います。

次回のイベントにもぜひ参加したいです。

ⓒ i-plug,inc. All Rights Reserved.