vol.7ですね。学生の頃はサッカーをやっていて、背番号は大体7番でした。今はアーセナル推し。
fujitani soraです。
交換Blogずにふみさんが入ってくれました。
うれしい
初めましてはコラコンの時ですね。
2回目が12月にある
【先着500名】CoLab Conf(コラコン)【U35限定テックカンファレンス】 - connpass
技術よりのテーマですが、友人との軽めのブログ交換って感じなので、そこまで厳密なことを書いているわけではありません。
詳しいことを知りたくなったらReferenceへどうぞ
Biome
ToolChainの統一を掲げて出てきたTypeScriptのlint/formatライブラリですが、ぼくのRust langへの興味の起点になってくれたのがこのBiomeだったりします。
よく言及されるであろう、既存ライブラリと比べた時の速度に関しては、正直当初は「別に既存linterの速度で困ることはないし、そんなに早くなってもな...」と考えていました。
加えてBiome1系ではno-floating-promiseなどの安全性に強く作用するruleがサポートされていなかったこともあり、自分のコントロール範囲では導入を見送っていました。
考え方を変えたのは、TSKaigi2025 AI Coding Agent Enablement in TypeScriptのセッションを拝見してからです。

人間とAIで速度に対する重要度が違うのは確かにそうで、人間が実行するツールと、実行コードが依存するツールとでは速度に対するプライオリティが違ったが、その差が縮まってくるようなニーズが生まれていると感じています。
Biome2系からは内部実装の変化もあり、上記で挙げた重要なruleへの対応や、GritQLによるcustom ruleのサポートも加速しています。
こうなってくると、依存がBiomeに統一されることや設計のシンプルさなども含めて、Biomeが今では第一選択肢に上がるようになりました。
一応、自分は別に既存ツールが嫌になったわけではないです。
Prettierとかにはたまにcontributionもさせていただいていますし。
そんなBiomeですが、やはり競合は多いようで、下記のエコシステムの変化を観測しています。
- oxc
- oxlint : https://www.npmjs.com/package/oxlint
- oxfmt : https://www.npmjs.com/package/oxfmt
- vite+ voidzero.dev
簡単には変えにくいRepositoryでTypeScriptを選択するときは、この辺りは検討する必要性がありそうですね
ast-grep
ast-grep | structural search/rewrite tool for many languages
抽象構文木を利用したgrep toolです。
通常のgrepでは文字列や正規表現によって検索を行います。よく使うのはfzf, rg, git grepとか。
対して、ast-grepではast構造を踏まえた抽象的な構造検索ができます。
ast-grep reference Pattern Syntaxより引用
Pattern Syntax | ast-grep
// Given this pattern $_FUNC($_FUNC) // it will match all function call with one argument or spread call test(a) testFunc(1 + 1) testFunc(...args)
具体的な文字列ではなく、検索に変数を利用したastパターン検索が可能
下記はRails projectで運用したast-grepの例です。
- erbでのxss脆弱性の可能性があるコードの検出
id: xss message: Potential XSS vulnerability detected. User input is being rendered without proper escaping. severity: hint language: Html note: | XSS (Cross-Site Scripting) occurs when user input is rendered in HTML without proper escaping. Use Rails' built-in escaping methods or sanitize user input before rendering. rule: kind: text regex: "<%=\\s*raw\\s+"
# 検出されるコード例 <%= raw @user.bio %> <%= raw user_input %> <%= raw content %> <%=raw@variable%>
- 変数を利用したpath traversal脆弱性の検出
id: path-traversal
message: Potential Path Traversal vulnerability detected. User input is being used to construct file paths without validation.
severity: hint
language: Ruby
note: |
Path Traversal (Directory Traversal) occurs when user input is used to construct file paths
without proper validation. This allows attackers to access files outside the intended directory.
Validate and sanitize file paths, and use File.basename() or similar functions.
rule:
any:
- pattern: Rails.root.join($$$, $VAR, $$$)
- pattern: File.join($$$, $VAR, $$$)
- pattern: send_file $VAR
# 検出されるコード例
# パターン1: Rails.root.join with variable
Rails.root.join('uploads', params[:filename])
Rails.root.join('data', user_input, 'file.txt')
# パターン2: File.join with variable
File.join('/var/www', params[:path])
File.join(base_path, user_id, filename)
# パターン3: send_file with variable
send_file params[:file]
send_file user.document_path
このようなprojectのruleに沿わないルールや脆弱性のあるコードの検出を、各言語毎の対応に比べて、ast-grepという汎用的なツールの利用によって知識やリソースを横展開できることにはメリットがあると感じています。
最近はAgentのルールにmdを介してast-grepのルールを読み込ませることも試しており、AIとの親和性にも期待大。
ソースコード起因で発生したインシデントからのフィードバックをast-grep ruleとして記載しておくことで再発防止に繋がるケースも期待できそうです。
また、ast-grepの特徴として、ast構造を利用したコード書き換えの機能があります。
最近で活用した事例としては、Remix2.9で導入されたSingle Fetchによる破壊的変更への対応がありました。
asis
export async function loader() {
const posts = await getPosts();
return json({
posts,
});
}
tobe
export async function loader(params) {
const posts = await getPost(params.id);
return posts;
}
端的に言うと、jsonで囲う必要がなくなった。それによるno-unused-importsからの削除も必要。
必要なdiffが100fileほどあったこともあり、単純に手を動かすにはブチギレ作業でしたが、ast-grepのwrite optionを利用することで最小工数で修正を終えることができました。
rules:
# json() の削除
- id: remove-json-wrapper
language: typescript
rule:
pattern: return json($OBJ)
fix: return $OBJ
# import { json } の削除
- id: remove-json-import
language: typescript
rule:
any:
- pattern: import { json } from "@remix-run/node"
# 他のimportがある場合は json のみ削除
fix: ""
# search ast-grep scan # exec ast-grep scan --update-all
NeoVimとの連携などもあり、個人的にはよく利用する推しツールです。
base64-chrome-transfer
これは自分の日曜大工成功例で、base64 encode/decodeをブラウザから簡単に行うためのChrome Extensionです。
ソースコードは、要件だけ伝えて改善していないこともあり、Denoで作った関数群をjsトランスパイルしてブラウザで動かせるようにするみたいな奇怪な操作をしています。いつか直す。
前提として、関わっているprojectで下記のようなつらみを感じていました。
- GraphQLサーバであり、http req/resでやり取りされるIDがbase64 encodeされている
- GraphQLのAPI実行にはApolloClientを使用しており、Webからlocalhost経由で実行していた。
- 特定データをDatabaseClientから確認したいときにはresponseから生のIDを知りたい、requestを実行する際にはecodeされていることが必要、みたいな時に「terminalを開いて
echo "Obj:12345" | base64と実行して変換してから操作を行う」みたいなことをしていた
このWindowの行き来に心を痛めた僕が片手間に作ったのがbase64-chrome-transferです。


こんな感じでApolloClientから移動せずにChrome拡張機能として開くことができ、自作ツールで開発体験が向上したいい例になりました。
DHHと話していて思ったのは、ツールをあれこれ選んでいるうちは多分幸せにはなれなくて、ほしいものは自分で作るのがよいということだった。我々はもっと色々自作するべきなのだ。
— 大倉雅史(OKURA Masafumi) (@okuramasafumi) 2025年9月4日
(実際、Albaを作って明らかに世界が広がった感覚はあった)
もっと自作やカスタムして不便なことを忘れていきたいですね
まとめ
意外と真面目に書いてしまった。
その他のツールだと今は、rv(Rust製のRuby Version Maneger)、mini.nvim(NeoVim Pluginのセットみたいな)、Temporal(JavaScriptの新しい日時操作API)なんかをチェックしています。
言うまでもないがClaude Codeとかも
次はふみさんですよろしく!!