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
210
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
45
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
210
最近の推しリンター、Oxlintをご紹介
apple_yagi
0
930
PR_TIMESにおけるFastlyの導入と運用について.pptx.pdf
apple_yagi
1
85
PR TIMESにおけるNext.jsとcacheの付き合い方
apple_yagi
4
5.9k
開発速度を上げつつ品質を保つためのフロントエンド開発
apple_yagi
1
1k
Other Decks in Technology
See All in Technology
組み立てて楽しむ AWS Blocks 入門
kmiya84377
0
220
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
1
1.5k
契約書画像からの情報抽出に特化した視覚接地モデルを育てる話
sansantech
PRO
1
150
分析AIエージェントを育てる、動く環境を育てる
codatum
0
140
ログラスのマルチプロダクトを 支える認証基盤 〜テナントごとに異なる統制とどう向き合うか〜
dada4386
3
410
AI時代だからこそ推したい!Gitコマンド再入門
munakata
0
150
BedrockとLambdaで作る リアルタイム進行型推理ゲーム
kawametho
0
190
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
130
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
2
390
Lambda MicroVMsが分からなすぎたので使い所を1から考えてみた
tsukuboshi
2
420
IR Today: Theory, Practice, and Agents
dtunkelang
0
350
1万名の社員が使う認証基盤で どう信頼性を担保するか?
kairim0
0
210
Featured
See All Featured
Embracing the Ebb and Flow
colly
88
5.2k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Evolving SEO for Evolving Search Engines
ryanjones
0
310
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Why Our Code Smells
bkeepers
PRO
340
58k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
2
350
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
300
Chasing Engaging Ingredients in Design
codingconduct
0
340
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
390
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
550
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
470
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 がマージされたら解決するはず まとめ