Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
forwardRef を禁止したくて Biome に PR を出した話
Search
Ryuya Yanagi
January 16, 2026
Technology
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
forwardRef を禁止したくて Biome に PR を出した話
Ryuya Yanagi
January 16, 2026
More Decks by Ryuya Yanagi
See All by Ryuya Yanagi
XO から Oxlint に移行した話
apple_yagi
0
43
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
210
最近の推しリンター、Oxlintをご紹介
apple_yagi
0
870
PR_TIMESにおけるFastlyの導入と運用について.pptx.pdf
apple_yagi
1
85
PR TIMESにおけるNext.jsとcacheの付き合い方
apple_yagi
4
3.2k
開発速度を上げつつ品質を保つためのフロントエンド開発
apple_yagi
1
1k
Other Decks in Technology
See All in Technology
AI時代の「技術的負債」の変質ー概念の終焉と再解釈、エージェントと共に向かう先
nwiizo
1
3.2k
「ピッケル本」日本語版は4.0(第6版)が出版されるべき / pickaxe4-nagoyark05
kakutani
2
270
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.6k
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
5
25k
.NET WebAssemblyで実現するクライアントサイドAI推論:NuGetからViteまで、2つのエコシステムを繋ぐビルド戦略
yamachu
1
480
人間はどの意思決定を手放せるのか
kawasima
15
8k
リアーキテクチャ後の障害ゼロを目指したShadow Testingの取り組み
nihonbuson
PRO
1
170
LLMに渡さなかった仕事
nanaism
0
1.4k
beyond jj: config & tools ecosystem
indirect
0
5.8k
事業課題から技術的負債に向き合う
sansantech
PRO
2
2.3k
バイブコーディング時代のWebアプリ開発入門~Cloud Runで学ぶセキュアなビルドとデプロイ
waiwai2111
1
140
ADKで始める業務改善 - AIエージェント開発時の考えと設計
harappa80
2
260
Featured
See All Featured
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
530
Tell your own story through comics
letsgokoyo
1
1.1k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Darren the Foodie - Storyboard
khoart
PRO
4
3.9k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
670
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
480
Embracing the Ebb and Flow
colly
88
5.2k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Transcript
forwardRef を禁止したくて Biome に PR を出した話 FE Yatai Talks vol.1
やなぎ PR TIMES フロントエンドエンジニア X:@apple_yagi こう見えて?二児のパパです
みなさん React 19 使ってますか?
Actions 系の hooks の追加 useActionState / useFormStatus / useOptimistic use
API の追加 静的サイト用の新しい DOM API の追加 react-dom/static に prerender / prerenderToNodeStream が追加 React Server Components / Server Actions forwardRef なしで ref を渡せるように変更 <Context.Provider> の代わりに <Context> を Provider としてレンダリングできるよ うに変更 etc.. React 19 の変更点
Actions 系の hooks の追加 useActionState / useFormStatus / useOptimistic use
API の追加 静的サイト用の新しい DOM API の追加 react-dom/static に prerender / prerenderToNodeStream が追加 React Server Components / Server Actions forwardRef なしで ref を渡せるように変更 <Context.Provider> の代わりに <Context> を Provider としてレンダリングできるよ うに変更 etc.. React 19 の変更点
// React v18 import { forwardRef } from "react"; const
MyInput = forwardRef(function MyInput({ placeholder }, ref) { return <input placeholder={placeholder} ref={ref} />; }); // React v19 function MyInput({ placeholder, ref }) { return <input placeholder={placeholder} ref={ref} />; } forwardRef は将来非推奨になる予定だが、まだ @deprecated はついていない 間違えて使う可能性があるので禁止したい forwardRef なしで ref を渡せるように変更
ESLint @eslint-react/no-forward-ref react-x/no-forward-ref Biome noReactForwardRef Oxlint 未対応 jsPlugins を用いて @eslint-react/no-forward-ref
などを 使用することができる forwardRef を禁止する Lint ルール
Biome を使っているプロジェクトで ルールを有効にしてみる
{ "linter": { "enabled": true, "rules": { "recommended": true, "nursery":
{ "noReactForwardRef": "error" } } }, "formatter": { "enabled": true } } noReactForwardRef を有効にする
あれ?エラーにならないな
Biome の内部実装を見てみる
impl Rule for NoReactForwardRef { fn run(ctx: &RuleContext<Self>) -> Self::Signals
{ let node = ctx.query(); let model = ctx.model(); let callee = node.callee().ok()?; let is_react_19 = ctx .get_service::<Option<(Utf8PathBuf, Arc<PackageJson>)>>() .and_then(|manifest| { manifest .as_ref() .map(|(_, package_json)| package_json.matches_dependency("react", ">=19.0.0")) }); if is_react_19 == Some(false) { return None; } is_react_call_api(&callee, model, ReactLibrary::React, "forwardRef").then_some(()) } } noReactForwardRef の内部実装の抜粋
package.json から React のバージョンを取得し、19.0.0 より下であれば None を返し、上であ れば forwardRef を使用しているか判定する
let is_react_19 = ctx .get_service::<Option<(Utf8PathBuf, Arc<PackageJson>)>>() .and_then(|manifest| { manifest .as_ref() .map(|(_, package_json)| package_json.matches_dependency("react", ">=19.0.0")) }); if is_react_19 == Some(false) { return None; } is_react_call_api(&callee, model, ReactLibrary::React, "forwardRef").then_some(()) noReactForwardRef の内部実装の抜粋
なるほど、わい pnpm catalogs 使ってるんやが
"Catalogs" are a workspace feature for defining dependency version ranges
as reusable constants. Constants defined in catalogs can later be referenced in package.json files. https://pnpm.io/catalogs 「カタログ」は、依存関係のバージョン範囲を再利用可能な定数として定義するための ワークスペース機能です。カタログで定義された定数は、後で package.json ファイルか ら参照できます。 by Nani 翻訳 pnpm catalogs とは
package.json に記述する React のバージョンが "catalog:" となるため、正しいバージョン を解決することができない # pnpm-workspace.yaml packages:
- "apps/*" - "packages/*" catalog: react: 19.2.1 react-dom: 19.2.1 # package.json { "devDependencies": { "react": "catalog:", "react-dom": "catalog:" } } pnpm catalogs とは
ちなみにこの問題は ESLint では発生しない
import module from "node:module"; import path from "node:path"; const _require
= module.createRequire(process.cwd() + path.sep); export function getReactVersion(): string { return _require("react").version; } export function create(context: RuleContext<MessageID, []>): RuleListener { // Skip if React version is less than 19.0.0 const version = getReactVersion() if (compare(version, "19.0.0", "<")) { return {}; } return { CallExpression(node) { ... }, }; } no-forward-ref の内部実装のイメージ(ESLint)
module.createRequire を使用して現在の作業ディレクトリ基準の require を作成し、 プロジェクトに入っている React のバージョンを取得する import module from
"node:module"; import path from "node:path"; const _require = module.createRequire(process.cwd() + path.sep); export function getReactVersion(): string { return _require("react").version; } Biome は Rust で実装されているので、この手法が使えず package.json をパースして React の バージョンを取得している React のバージョンの取得方法
この問題を解決するために pnpm-workspace.yaml からバージョンを取得できるようにする Pull Request を出してみた(出してから時間が経ってしまったのでマージされるかは怪しい) https://github.com/biomejs/biome/pull/8396 ただ、最近 yarn と
bun にも catalogs 機能があることに気づいたのでそちらは別途対応が必要 となる yarn catalogs は pnpm catalogs と同じ記法だが、bun catalogs は package.json に catalog を定義する そもそもバージョンの取得方法を根本的に変えた方が良いか? 作業ディレクトリの node_modules の中を探索するとか 有識者の方、ご意見お待ちしております この問題の解決策として
React 19 では forwardRef を書く必要はなくなった 将来非推奨になる予定 ESLint/Biome には forwardRef を禁止する
Lint ルールがある Biome は今のところ pnpm catalogs を解決できない 自分の PR がマージされたら解決するはず まとめ