Microsoft

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars34,286
mentions960
06531.3K2K2.6KOct 4Oct 18Nov 2
UTC days · repositories Microsoft owns328 repositories

Package downloads

Cumulative recorded downloads · since 2025-10-17

crates.io—
npm47B
PyPI—
011.8B23.5B35.3B47BOct 4Oct 18Nov 2
Nov 2crates.io: 0/139 packages observed · npm: 3/265 packages observed · PyPI: 0/96 packages observed

Across 500 known packages in repositories Microsoft owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete. PyPI excludes known mirrors.

Top repositories

Microsoft’s repositories ranked by pull request authors, as on trending.

Loading

Contributes to

Repositories outside Microsoft’s account where Microsoft opened or reviewed pull requests in the past 365 days.

Who noticed Microsoft

Everyone who starred or forked Microsoft’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

963posts
Nov 316 posts
  1. .NET 8・.NET 9のサポート終了は2026年11月10日|同日終了の理由と.NET 10への移行ガイド Microsoftは標準期間サポート(STS)の期間を18か月から24か月に延長しました。その結果、.NET 9は.NET 8と同じ2026年11月10日にサポートが終了します。本記事では、その理由と.NET 10へのアップグレード方法を解説します。 .NET 9のサポートは2026年11月10日に終了します。.NET 8も同じ日です。残りは3週間を切りました。.NET 8は2023年11月14日にリリースされた長期サポート(LTS)版、.NET 9はその1年後の2024年11月12日にリリースされた標準期間サポート(STS)版です。この2つが同じ日にサポート終了を迎えます。誤植ではありません。11月10日以降にサポートされるバージョンは.NET 10で、LTSとして2028年11月14日までサポートされます。 2026年11月10日に.NET 8と.NET 9で何が終わるのか? 終わるのはサービシング(保守提供)です。.NET BlogでRahul Bhandari氏が公表した告知によると、Microsoftは.NET 8と.NET 9に対する「サービシング更新、セキュリティ修正、技術サポート」を終了します。 アプリケーションは引き続き動作します。自動でアンインストールされることもありません。ランタイム、SDK、コンテナイメージもダウンロードできます。ただし、今後は修正が提供されなくなります。 11月10日はパッチ・チューズデーでもあります。Microsoftによると、既知の重大な問題がある場合に限り、.NET 8と.NET 9は同日に最後の更新を1回ずつ受け取る可能性があります。それ以降は、ランタイム、ASP.NET Core、基底クラスライブラリ(BCL)に影響する新たなCVEはすべて自己責任で対処することになります。 本記事執筆時点の最新パッチは8.0.32と9.0.21で、どちらも2026年10月13日にリリースされています。これらを適用していない場合は、期限を迎える前から対応が遅れている状態です。 ツール面にも影響があります。今後のVisual Studio 2022のサービシング更新で、.NET 8と.NET 9のコンポーネントがサポート終了として扱われるようになります。Visual Studioは更新時に、サポート終了のコンポーネントの削除を提案します。ビルドエージェントでこの設定を事前に確認しておきましょう。 なぜ.NET 9は.NET 8と同じ日にサポートが終わるのか? .NET 9のサポート期間中に、MicrosoftがSTSのライフサイクルを変更したためです。 旧ポリシーでは、STSのサポート期間は18か月でした。これは次のリリースから6か月後にあたります。.NET 9は2026年5月12日にサポートが終了する予定でした。 2025年9月16日、.NET BlogでJamshed Damkewala氏が、STSリリースのサポート期間を24か月に延長すると発表しました。.NET 9から適用されます。LTSは従来どおり3年です。これにより、.NET 9のサポート終了日は2026年5月12日から2026年11月10日に移り、.NET 8の終了日とちょうど重なりました。 STSを24か月に延ばしたことで、STSリリースの終了日は直前のLTSリリースと同じになります。STS版の依存関係を使っていても、LTS版アプリと同じ日にサポートが終わる形です。なお、.NET Aspireのようなアウトオブバンド(OOB)コンポーネントは独自のライフサイクルを持つため、別途確認が必要です。 実際の問題を解消する、妥当な見直しだと私は考えています。一方で、副作用として2つのリリースが同じ日にサポートカレンダーから外れることになりました。.NET 9の終了を2026年5月と見込んで計画していた方は、6か月の猶予が増えていたことに気づいていないかもしれません。 この構造は今後も繰り返されます。偶数番号のLTSは11月にリリースされ、3年間サポートされます。奇数番号のSTSは翌年の11月にリリースされ、新ポリシーでは2年間サポートされます。どちらも同じ11月に終了します。.NET 10と.NET 11も、2028年11月に同じ日にサポートが終わると私は見ています。今回は例外ではなく、これからの標準パターンです。 各.NETバージョンのサポート状況は? 出典: .NET and .NET Core Support Policy(2026年10月19日時点) どのバージョンにアップグレードすべきか? .NET 10です。 現行のLTSリリースで、2028年11月14日までサポートされます。24か月のSTSポリシーのもとでは、.NET 11を待っても猶予は延びません。得られるのは、同じ月にサポートが終わると私が見ている、より新しいリリースだけです。 .NET 9をお使いなら、.NET 10へは1バージョン上げるだけで、多くの場合は小規模な変更で済みます。.NET 8をお使いなら、2リリース分の破壊的変更をまたぐため、工数を多めに見込んでください。ASP.NET Coreアプリは、ASP.NET Core 9から10への移行ガイドも確認しておきましょう。 最も単純な場合、アップグレードは各プロジェクトファイルの1行の変更です。 net10.0 ただし、この1行で済むことはまれです。実際の作業は次のような部分に生じます。 - 互換リリースが必要なNuGetパッケージ - 古いSDKを固定しているglobal.json - mcr.microsoft.com/dotnet/aspnet:8.0を参照しているDockerfile - 新しいランタイムのインストールが必要なCI/CDパイプラインとホスティング環境 自社で運用していても開発はしていないサードパーティ製アプリケーションについては、ベンダーに.NET 10対応版のリリースを問い合わせてください。 GitHub Copilotで.NET 10にアップグレードするには? .NET Upgrade Assistantは使いません。Microsoftのドキュメントでは、「.NET Upgrade Assistant is officially deprecated.」と明記されています。サポート終了の告知にはまだリンクが残っていて紛らわしいのですが、このツールは後継に置き換えられています。 後継はGitHub Copilot upgrade agentです。ソースコードとプラグインはmicrosoft/upgrade-agent-pluginsにあります。Mika Dumont氏がModernize .NET Anywhere with GitHub Copilotで使い方を解説しています。 作業は3つの段階で進みます。各段階の成果物はリポジトリの.github/upgrades/配下にMarkdownファイルとして出力されるので、レビューやコミットが可能です。 1. 評価(Assess): プロジェクトと依存関係を調べ、assessment.mdを出力します。破壊的変更、API互換性の問題、非推奨パターンが一覧化されます。 2. 計画(Plan): plan.mdを出力します。アップグレード戦略、依存関係の順序、リスクが記載されます。 3. 実行(Execute): 計画をtasks.mdのタスクに分割して順に実行し、作業単位ごとにGitコミットを作成します。検証やロールバックを段階的に行えます。 利用できる環境は4つあります。普段使っているものを選んでください。 - Visual Studio: Visual Studio 2026、またはVisual Studio 2022 17.14.16以降で、ソリューションエクスプローラーのソリューションまたはプロジェクトを右クリックし、Modernizeを選択します。 - VS Code: GitHub Copilot upgrade extensionをインストールし、Copilot ChatのエージェントピッカーでUpgradeを選択します。 - GitHub Copilot CLI: 次のコマンドを実行します。 /plugin marketplace add microsoft/upgrade-agent-plugins /plugin install upgrade-agent@upgrade-agent-plugins /agent Upgradeを選び、「upgrade my solution to .NET 10」のように指示します。 - GitHub: Copilotクラウドエージェントとして追加すると、プルリクエストを自動で作成できます。手順はクラウドエージェントのREADMEを参照してください。この方法には、クラウドエージェントが使える有料のCopilotプランと、リポジトリへの書き込み権限が必要です。 どの方法を選ぶにしても、次の点をおすすめします。 - 最初は、モノリスではなく小さなライブラリやサービスから始めましょう。自社のコードベースでエージェントがどこでつまずくかを把握できます。 - 大規模なコードでは、ガイドモード(Guided)を使いましょう。「pause」でガイドモードに、「continue」で自動モードに戻せます。 - 最後にまとめてではなく、コミットごとにテストスイート全体を実行しましょう。タスクごとにコミットされるため、コストを抑えられます。 - 完了後は、次のコマンドで結果を確認しましょう。 dotnet --list-runtimes dotnet list package --outdated 大規模なレガシーソリューションでは、エージェントが自力で最後までやり遂げられるとは限りません。大きなアプリで処理が止まるという初期ユーザーの報告もあり、Microsoftがリポジトリでフィードバックを集めています。移行の全工程ではなく、非常に速い初回パスとして使ってください。 2026年11月10日までに.NET 8・.NET 9からアップグレードできない場合は? その場合は、運用中のバージョンにパッチを提供してくれる存在が必要です。 HeroDevsのNever-Ending Support(NES)for .NETは、.NET 6、.NET 8、.NET 9をそのまま置き換えられる、安全なドロップイン代替です。ランタイム、ASP.NET、Entity Framework、.NET SDK、WPF、WinFormsを対象とし、NES for .NET Containersを使えばコンテナイメージもカバーします。コードの変更は不要です。 HeroDevsは.NET Security Groupのメンバーです。そのため、.NETに影響する脆弱性の事前開示を受け、MicrosoftのパッチTuesdayのリリースと同時に、EOLバージョン向けの修正済みビルドを提供できます。 これは仮定の話ではありません。.NET 6は2024年11月12日のサポート終了以来、HeroDevsがパッチを提供し続けています。System.Net.MailのSMTPインジェクションの脆弱性であるCVE-2026-32178では、.NET 6に上流の修正が提供されませんでしたが、NESのお客様には修正が提供されました。2026年11月11日からは、.NET 8と.NET 9もこの対象に加わります。 NESは.NET 10への移行の代わりにはなりません。移行のスケジュールを、パッチ・チューズデーではなく、エンジニアリングチームが決められるようになるということです。 よくある質問(FAQ) .NET 8と.NET 9のサポートが終了するのは正確にいつですか? どちらも2026年11月10日です。この日はパッチ・チューズデーで、既知の重大な問題がある場合に限り、Microsoftが各バージョンに最後の更新を1回提供する可能性があります。 .NET 9は2026年5月にサポート終了の予定ではなかったですか? はい、旧ポリシー(STS 18か月)では2026年5月12日でした。Microsoftが2025年9月16日にSTSを24か月に延長し(.NET 9から適用)、終了日が2026年11月10日に移りました。 .NET 8や.NET 9のアプリケーションは動かなくなりますか? いいえ、引き続き動作します。ただし、Microsoftからのセキュリティ修正、バグ修正、技術サポートは提供されなくなります。 .NET Upgrade Assistantはまだサポートされていますか? いいえ。MicrosoftはGitHub Copilot upgrade agentに置き換える形で非推奨としました。後継はVisual Studio 2026とVisual Studio 2022 17.14.16以降に付属し、VS Code、Copilot CLI、GitHubでも利用できます。 .NET 10ではなく.NET 11を待つべきですか? いいえ。.NET 11はSTSリリースで、24か月ポリシーのもとでは.NET 10と同じ2028年11月ごろにサポートが終了する見込みです。.NET 10はすでに利用でき、より安全な移行先です。 HeroDevsは11月10日以降も.NET 9をサポートしますか? はい。NES for .NETは、.NET 6、.NET 8、.NET 9をカバーします。 11月10日の期限までにアップグレードが間に合わない場合 .NET 10への移行が2026年11月10日に間に合わないアプリケーションについては、NES for .NETが.NET 6、8、9にパッチを提供し続け、監査対応も維持します。その間に、慌てず適切に移行を進められます。保証範囲についてはHeroDevsにお問い合わせください(日本語で対応可能です)。 --- お問い合わせ 本記事の内容やHeroDevsのソリューション(NES等)について、日本語でのお問い合わせに対応しています。お気軽にHeroDevsお問い合わせページからご連絡ください。 --- 原文: herodevs.com (出典: herodevs.com)

  2. GitHub Copilot App のサンドボックスで .NET アプリを開発するための設定を試してみた GitHub Copilot App のローカルサンドボックスが GA したらしいので、.NET の開発で使えそうかどうか見てみようと思います。 今回は Windows 環境で、コンソールアプリの作成・実行と NuGet パッケージの追加を試し、その後に Minimal API も動かしてみました。 コンソールアプリは動かせましたが、ファイルのアクセス許可を調整したり、NuGet のエラーを調べたりする必要がありました。Minimal API は起動したものの、エンドポイントへのアクセスがタイムアウトし、今回はそこで断念しました。 ワークツリーの保存先を変更している場合の注意 GitHub Copilot App のワークツリーの保存先を D ドライブなどに変更している場合は、デフォルトの C ドライブ配下の場所に戻す必要があります。 現在、Windows のサンドボックスでは、システムドライブ以外にあるフォルダーを作業場所にすると、シェルでフォルダーの一覧取得などができない問題が報告されているためです。以下の Issue でも、D ドライブなどではアクセス拒否になり、システムドライブの C ドライブでは動くことが確認されています。 copilot-cli#5207 コンソールアプリを作成して実行するための設定 GitHub Copilot App にコンソールアプリの作成と実行を依頼したところ、dotnet new console の実行時にアクセス拒否のエラーが出ました。.NET SDK やテンプレートが使うフォルダーへの読み書きを許可する必要がありました。 使ったのは .NET 10 で、global.json で SDK を 10.0.403 に指定しています。 アクセスを拒否されたのは次のパスです。 %USERPROFILE%.dotnet\10.0.403.toolpath.sentinel %USERPROFILE%.templateengine\dotnetcli\10.0.403 %USERPROFILE%.templateengine\packages.json そこで、GitHub Copilot App のサイドバーから Settings を開き、Repositories で対象のリポジトリを選びます。Sandbox にある Additional read/write の Add folder から、次のフォルダーを追加しました。 C:\Users<ユーザー名>.dotnet C:\Users<ユーザー名>.templateengine <ユーザー名> は自分の環境に合わせて置き換えてください。 設定を変更しただけでは実行中のセッションに反映されないので、/restart-session でセッションを再起動する必要があります。 docs.github.com 上記のフォルダーへのアクセスを許可してセッションを再起動した後、Copilot に再実行を依頼すると、dotnet new console でのアプリ作成と、dotnet run での Hello, World! の表示に成功しました。 NuGet パッケージの追加を試してみる コンソールアプリの作成と実行ができたので、続いて Copilot に ReactiveProperty の追加を依頼しました。Copilot が実行したのは次のコマンドです。 dotnet add .\HelloWorld\HelloWorld.csproj package ReactiveProperty ところが、パッケージの追加もアクセス拒否で失敗しました。エラーメッセージには、拒否されたパスが出ていません。 error: Access to the path is denied. NuGet のパッケージ保存先やキャッシュのフォルダーが怪しいと思い、Additional read/write に次の4つを追加しました。 C:\Users<ユーザー名>.nuget C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch C:\Users<ユーザー名>\AppData\Roaming\NuGet C:\Users<ユーザー名>\AppData\Local\NuGet 設定を反映して Copilot に再実行を依頼しましたが、それでも Access to the path is denied. が解消しませんでした。 ログを確認すると、次の URL からパッケージの登録情報を取得する GET リクエストには 200 OK が返っていました。少なくとも、この通信には成功しています。 api.nuget.org そこで、Copilot に NUGET_SHOW_STACK を有効にして再実行してもらいました。スタックトレースでは、NuGet.Protocol.HttpCacheUtility.CreateCacheFileAsync から呼ばれた System.IO.FileSystem.MoveFile で失敗していました。登録情報の取得ではなく、キャッシュファイルの移動で止まっていることが分かりました。 フォルダーの許可を追加しても解決せず、ログからもアクセスを拒否されたパスが分からなかったので、Process Monitor で実際のアクセス先を調べることにしました。 Process Monitor で失敗した操作を見る エラーメッセージだけでは先に進めなかったので、Microsoft の Process Monitor(Procmon)を使って、もう一度パッケージ追加を実行したときのファイル操作を確認しました。 learn.microsoft.com そこで見つかったのは、次の場所にあるファイルのリネームの失敗でした。ユーザー名やサンドボックスごとに変わる部分は置き換えています。 %LOCALAPPDATA%\Packages\sandbox.{GUID}\AC\NuGet\v3-cache<source-cache-dir>\list_reactiveproperty_index.dat-new list_reactiveproperty_index.dat-new の名前を、同じディレクトリ内で list_reactiveproperty_index.dat に変えようとしたところ、アクセスを拒否されていました。Procmon では、このリネーム操作(SetRenameInformationFile)の結果が ACCESS DENIED と記録されていました。 実際のアクセス先が AppData\Local\Packages 配下だったので、Additional read/write に次のパスを追加しました。 C:\Users<ユーザー名>\AppData\Local\Packages セッションを再起動して Copilot にパッケージ追加を再実行してもらうと、ReactiveProperty 9.10.0 と依存パッケージの導入に成功しました。値の変更を Subscribe で受け取り、コンソールに出力する処理も動きました。 これで動くようになりました。ただ、ここまでにいくつかのフォルダーを許可しているので、全部必要だったかは確認していません。AppData\Local\Packages を丸ごと許可するのは範囲が広いので、もう少し絞れないかは気になるところです。 私の環境でコンソールアプリを実行できた設定例 試した結果、ユーザー設定の Additional read/write(Folders the sandbox may read and modify)に残っていた .NET 用のパスは次の 7 件です。 C:\Users<ユーザー名>.dotnet C:\Users<ユーザー名>.templateengine C:\Users<ユーザー名>.nuget C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch C:\Users<ユーザー名>\AppData\Roaming\NuGet C:\Users<ユーザー名>\AppData\Local\NuGet C:\Users<ユーザー名>\AppData\Local\Packages 設定する場合は、C:\Users<ユーザー名> の部分を自分の環境の絶対パスに置き換えてください。ここでは設定画面で環境変数が展開されるかどうかは確認していないので、絶対パスで記載しています。 これとは別に、添付画像へアクセスするために追加したパスもありました。 C:\Users<ユーザー名>.copilot\workspaces こちらは .NET の実行用ではなく、添付画像へのアクセス用です。 私の環境では、この設定でコンソールアプリの作成・パッケージ追加・実行までできました。もう少し許可するフォルダーを減らせるかもしれませんが、そこまでは試していません。 特に AppData\Local\Packages は、広い範囲の読み書きを許可することになります。今回の実験で使った設定であって、全員にそのまま追加することを勧めるものではありません。どこまで権限を絞っても動くかは未確認です。 Minimal API も試してみる コンソールアプリが動いたので、次は Copilot に Minimal API の作成と実行を依頼しました。アプリは起動しましたが、エンドポイントにアクセスするとタイムアウトしてしまいました。 サンドボックス設定の Outbound internet と Local network は、セッション開始時からどちらも ON にしていました。それでも接続できなかったので、ネットワーク周りの制約を調べてみました。 調べていると、Microsoft の MXC の公開資料で、似た症状の既知の制約を見つけました。Windows の特定の構成では、ホストからサンドボックス内で起動したサーバーへの接続がタイムアウトするというものです。 github.com/microsoft/mxc/blob/main/docs/backends/… リンク先では、Windows build 26691.1002 で、サンドボックスから外への通信をプロキシー経由に限定して試していました。ホストとのループバック通信を許可しても、ホストからサンドボックス内のサーバーへの接続はタイムアウトしたそうです。一方、プロキシーを使わない別の構成では接続できたとのことでした。 今回もこの制約に当たったのかは分かりません。ただ、起動した API に接続できない状態では開発を進められないので、今回はここまでにしました。 まとめ 今回は、サンドボックスのアクセス許可を追加することで、コンソールアプリの作成から NuGet パッケージの追加、実行までできました。ただ、途中で Procmon を使ってアクセス先を調べる必要があり、Minimal API も接続できないところで止まってしまいました。 今回試した Windows のローカル環境では、現時点で自分の実開発に使うにはまだ厳しいと感じました。サンドボックス自体は重要だと思っているので、今後の改善も追っていきたいです。

  3. Microsoft.UI.Reactorを学習する Microsoft.UI.Reactorとは Microsoft.UI.Reactor は、C#で WinUI アプリを宣言的に作る実験的なフレームワークです。 ※2026/11/01時点で 0.1.0-preview.16 版です。 試す プロジェクトを作成する winget install Microsoft.WinAppCli winapp new -t reactor -n Kashin777.UI.Reactor cd Kashin777.UI.Reactor 構成 !image.png csproj(抜粋) <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!-- Windows GUI アプリとしてビルド --> <OutputType>WinExe</OutputType> <!-- .NET 10 と Windows SDK 10.0.26100.0 を対象にする --> <TargetFramework>net10.0-windows10.0.26100.0</TargetFramework> <!-- サポートする Windows の最低バージョン --> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion> <!-- WinUI アプリとしてビルドし、MSIX のビルド機能を有効にする --> <UseWinUI>true</UseWinUI> <EnableMsixTooling>true</EnableMsixTooling> <!-- C# の基本設定 --> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <!-- Windows アプリのビルドに必要なパッケージ --> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="*" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="*" /> <PackageReference Include="Microsoft.Windows.SDK.BuildTools.WinApp" Version="*" /> <!-- Microsoft.UI.Reactor --> <PackageReference Include="Microsoft.UI.Reactor" Version="0.1.0-preview.16" /> </ItemGroup> </Project> App.cs using Microsoft.UI.Reactor; using Microsoft.UI.Reactor.Core; using Microsoft.UI.Reactor.Layout; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using static Microsoft.UI.Reactor.Factories; // To learn more about Reactor, the Reactor project structure, and more about // our project templates, see: https://github.com/microsoft/microsoft-ui-reactor ReactorApp.Run<App>("Kashin777.UI.Reactor"); class App : Component { public override Element Render() { var titleBar = TitleBar("Kashin777.UI.Reactor") .Flex(shrink: 0); // This is the main content area of your application. // Add your UI elements here. var content = Border(Empty()).Flex(grow: 1, basis: 0); return FlexColumn(titleBar, content) .Backdrop(BackdropKind.Mica); } } とりあえず実行 dotnet run !image.png 画面を実装する 公式ドキュメントのCounter Example に従い、App.cs を修正してみます。 public override Element Render() { var titleBar = TitleBar("Kashin777.UI.Reactor") .Flex(shrink: 0); var (count, setCount) = UseState(0); // countプロパティとsetterを作成 var content = VStack(spacing: 12, // Vertical StackElement TextBlock($"Count: {count}").FontSize(20).SemiBold(), // element[0] TextBlock HStack(spacing : 8, // element[1] Horizontal StackElement Button("- 1", () => setCount(count - 1)), // 1デクリメント Button("Reset", () => setCount(0)), // リセット Button("+ 1", () => setCount(count + 1)) // 1インクリメント ) ).Padding(24); return FlexColumn(titleBar, content) .Backdrop(BackdropKind.Mica); } dotnet run !image.png 基礎 フック フック インタラクティブなUIには必ず状態が必要です。Reactorでは、状態はUseState時間とともに変化する値を管理するための主要なフックです。 コンポーネントは複数回呼び出すことができUseState、各呼び出しは独立した値を追跡します。 var (count, setCount) = UseState(0); var (firstName, setFirstName) = UseState(""); var (fontSize, setFontSize) = UseState(16.0); | フック | 戻り値 | 目的 | |--|--|--| | UseState | (T value, Action<T> set) | リアクティブな状態 — set 時に再レンダリングされます。 | | UseReducer | (T value, Action<Func<T,T>> update) または (TState, Action<TAction>) | 関数型または Redux スタイルの更新。 | | UseEffect | void | コミット後の副作用。Func<Action> オーバーロードを使用すると、次のエフェクトの実行前およびアンマウント時にクリーンアップが実行されます。 | | UseMemo | T | 計算結果のキャッシュ。依存項目のいずれかが不等となった場合に再実行されます。 | | UseRef | Ref<T>(mutable .Current 付き) | 変更時でも再レンダリングを行わずに、レンダリング間を通じて状態を保持します。 | | UseCallback | Action | レンダリング間を通じて安定したデリゲート識別子。 | | UseContext | T | 周囲の Context 値を読み取ります。 | | UseObservable | T | 追跡対象の INotifyPropertyChanged ソースが変更を発生させた際に再レンダリングを行います。 | | UseExternalStore | TSnapshot | subscribe/getSnapshot ストアを Reactor にブリッジし、スナップショットが変更された場合にのみ再レンダリングします。 | | UseResource | AsyncValue<T> | キャッシュされた非同期読み取り(「非同期リソース」を参照)。 | | UsePersisted | (T, Action<T>) | プロセス内のアンマウント/リマウント後も存続する UseState — メモリ内、終了時にクリアされます(「永続性」を参照)。 | レイアウト レイアウト | 要素 | 目的 | |--|--| | VStack | 縦積み(上から下へ子要素を配置) | HStack | 水平スタック(左から右へ) | Grid | 行/列グリッド(比例サイズ) | ScrollView | オーバーフローコンテンツ用のスクロール可能なラッパー | Border | 背景、角丸、ストローク付きコンテナ コントロール コントロールカタログ | カテゴリ | 中身は? | |--|--| | フォーム | テキスト入力、ピッカー、ボタン、検証プリミティブ | | コレクション | リスト、グリッド、仮想化リスト、リピーター | | テキストとメディア | 見出し、リッチテキスト、画像、メディアプレーヤー | | ステータスと情報 | 進捗状況、情報バー、バッジ、指導のヒント | | レイアウトとコンテナ | スタック、グリッド、境界線、スクロールホスト、ペイン | | ナビゲーション | ナビゲーションビュー、フレーム、タブ、パンくずリスト、ピボット | | 図形とアイコン | 長方形、楕円、線、パス、アイコンのソース | | ダイアログとフライアウト | コンテンツダイアログ、メニューフライアウト、コマンドバーフライアウト | | データシステム | DataGrid、列、データソース、ページング | | チャート作成 | 線グラフ、棒グラフ、面積グラフ、円グラフ、力グラフ | ホットリロード ホットリード dotnet watch run アプリを起動したまま、ボタンのラベルを変更して保存したら PS C:\Users\Kashin777\source2\repos\Kashin777.UI.Reactor> dotnet watch run dotnet watch 🔥 Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload. dotnet watch 💡 Press Ctrl+R to restart. 復元が完了しました (0.0 秒) 0.1 秒後に 成功しました をビルド info NETSDK1057: プレビュー版の .NET を使用しています。https://aka.ms/dotnet-support-policy をご覧ください Kashin777.UI.Reactor net10.0-windows10.0.26100.0 win-x64 成功しました (0.4秒) → bin\Debug\net10.0-windows10.0.26100.0\win-x64\Kashin777.UI.Reactor.dll 0.5 秒後に 成功しました をビルド dotnet watch ⌚ Loading projects ... dotnet watch ⌚ Loaded 1 project(s) in 0.5s. C:\Users\Kashin777\source2\repos\Kashin777.UI.Reactor\Properties\launchSettings.json からの起動設定を使用中... ⠼ Launching packaged application... ✅ 43A37F59-B43C-4C5A-9E09-1DE873E18ECA_1z32rh13vfry6 launched (PID: 22536) dotnet watch ⌚ File updated: .\App.cs dotnet watch ⚠ [Kashin777.UI.Reactor (net10.0-windows10.0.26100.0)] Further changes won't be applied to this process. ドキュメントに従い dotnet watch run で起動したのですが、App.cs の変更は検知されるもののリロードされず...

  4. JSX が JavaScript になるまで React のコンポーネントには、こんなコードを書きます。 return <h1 className="title">Hello, {name}!</h1>; 見た目はほとんど HTML です。でも、よく見ると HTML ではありません。React の JSX では、属性は class ではなく className ですし、{name} のように JavaScript の式がそのまま埋め込まれています。かといって、JavaScript にも return の後ろにタグを書く構文はありません。 では、ブラウザはこのタグを HTML として読んでいるのでしょうか。それとも JavaScript として読んでいるのでしょうか。 答えはどちらでもありません。ブラウザに届く時点で、このタグはもう残っていないからです。筆者も「ビルドのときに何かに変換されている」ことは知っていました。ただ、何に変換されて、ブラウザが最終的に何を受け取っているのかは説明できませんでした。この記事では、変換の途中でできるもの(中間生成物)を 1 つずつ取り出しながら、.jsx に書いたタグが JavaScript になり、実行されて何を返すのかまでを追いかけます。 この記事の前提 環境: React 19.3.1 / react-dom 19.3.1 / Node.js v26.12.1 / macOS ブラウザでの確認: Vite 8.3.5(@vitejs/plugin-react 6.1.2)/ Google Chrome 156.0.8078.80 変換ツール: Babel(@babel/core 8.0.9・@babel/preset-react 8.0.1・@babel/parser 8.0.8)を主に使い、比較用に TypeScript 7.0.2 の tsc / SWC(@swc/core 1.16.20)/ esbuild 0.28.2 / Oxc(oxc-transform 0.156.0)も使います。TSX のコラムでは、ほかに @babel/preset-typescript 8.0.7・@babel/plugin-syntax-typescript 8.0.3・@types/react 19.3.0 を使います 対象: React の標準の変換方式(automatic runtime)。断りがない限り、開発用の出力(development)はオフにした結果を載せています 題材: 小さなコンポーネントを書いた App.jsx が中心です。TypeScript(.tsx)の場合に何が変わるかは、末尾のコラムで扱います 範囲外: 変換後のオブジェクトが Fiber になり DOM に反映される過程(reconcile)、Hooks の実装、Server Components 記事中のログ・エラーメッセージ・出力は、すべて筆者が上記環境で実際に採取したものです。AST のダンプと 5 つのツールの比較は、それぞれのツールを Node.js から呼ぶ小さなスクリプトによるものです 全体像 パーサー — JSX を構文として読める。ソースを AST(構文木)にし、タグを JSXElement などのノードとして表す。各変換ツールが内蔵している(Babel なら @babel/parser) 変換 — AST の JSX のノードを関数呼び出し(_jsx(...))に書き換え、呼び出し先の import を差し込む。Babel・SWC・esbuild・Oxc・tsc などが担う ランタイム(react/jsx-runtime) — 変換後の _jsx(...) の呼び出し先。React Element と呼ばれるただのオブジェクトを返す レンダラー(react-dom) — React Element を受け取り、ブラウザでは DOM を組み立てる(サーバーでは HTML 文字列にもできる)。この記事では中身には踏み込まない ブラウザが受け取っているのは、タグが関数呼び出しに置き換わった普通の JavaScript です。 その JavaScript を実行したあと、react-dom が DOM を組み立てます。 どの関数をどの形で呼ぶかは、JSX の構文自体には決まっていません。React の automatic runtime では、呼ぶのは react/jsx-runtime の jsx(type, props, key) で、この形は React が定めた約束です。変換ツールは、呼び出し先の設定(importSource など)で指定された先に向けて、この約束どおりに書き換えます。そのため、どの変換ツールを使っても、ほぼ同じ JavaScript になります。 課題 — React を書いていて浮かぶ疑問 冒頭の疑問ともう 1 つ、次の 2 つに答えます。 ブラウザは JSX のタグを HTML として読んでいるのか、JavaScript として読んでいるのか JavaScript はスクリプト言語で、書いたファイルをそのまま渡せば動くはずなのに、なぜ React のプロジェクトはデプロイの前にビルドが要るのか 題材は、Fragment(<>)・属性・埋め込みの式・イベントハンドラ・key が一通り入った小さなコンポーネントです。 // App.jsx import { useState } from "react"; export function App({ name }) { const [count, setCount] = useState(0); return ( <> <h1 className="title">Hello, {name}!</h1> <button onClick={() => setCount(count + 1)}> count is {count} </button> {[1, 2].map((n) => <li key={n}>{n}</li>)} </> ); } 試したこと — 中間生成物を段階ごとに取り出す 段階 0: JavaScript のエンジンは JSX を読めない まず、変換をせずにそのまま実行してみます。JSX を含むファイルを .mjs として Node.js に渡しました。 $ node stage0/hello.mjs const el = <h1>hi</h1>; ^ SyntaxError: Unexpected token '<' タグの 1 文字目 < で構文エラーです。拡張子を .jsx にした場合は、プロジェクトの設定で結果が変わりました。package.json が "type": "module" なら構文を読む前に ERR_UNKNOWN_FILE_EXTENSION で弾かれ、CommonJS なら .js として読まれて同じ SyntaxError になります。 変換をしない静的なサーバーから、次の HTML を Chrome で開きました。 <script type="module"> const el = <h1>hi</h1>; </script> コンソールには、Node.js と同じエラーが出ました。 SyntaxError: Unexpected token '<' JSX は ECMAScript(JavaScript の標準仕様)には入っていない構文拡張です。JSX 自体の仕様の草案(react/jsx、旧 facebook/jsx)も、エンジンやブラウザが実装することは想定していないと冒頭で断っていて、何に変換されるかも定めていません。つまり、ブラウザは JSX を HTML としても JavaScript としても読めません。JSX は、ブラウザに届く前に必ず誰かが JavaScript に変換している構文です。1 つ目の疑問への答えの半分がこれです。 2 つ目の疑問「なぜビルドが要るのか」の答えの中心も、ここにあります。ブラウザに渡す前に JSX を JavaScript へ変換する工程が要り、それを担っているのがビルドです。開発中に同様の変換をしているのは開発サーバーで、その様子は段階 2 の最後で見ます。 段階 1: パーサー — タグは JSX 専用のノードになる 最初の仕事は、JSX を読めるパーサーで AST を作ることです。Babel のパーサー(@babel/parser に jsx プラグインを付けたもの)で、return (...) の中身をダンプしました。長いので <h1> と <button> の部分を抜きます。 JSXFragment JSXOpeningFragment JSXText "\n " JSXElement JSXOpeningElement JSXIdentifier "h1" JSXAttribute JSXIdentifier "className" StringLiteral "title" JSXText "Hello, " JSXExpressionContainer Identifier "name" JSXText "!" JSXClosingElement JSXIdentifier "h1" JSXText "\n " JSXElement JSXOpeningElement JSXIdentifier "button" JSXAttribute JSXIdentifier "onClick" JSXExpressionContainer ArrowFunctionExpression (略) JSXText "\n count is " JSXExpressionContainer Identifier "count" JSXText "\n " JSXClosingElement JSXIdentifier "button" (以下 map の JSXExpressionContainer) 普通の JavaScript の AST には無い、JSX で始まるノードが並んでいます。タグ名の h1 も、JavaScript の識別子を表す Identifier ではなく、JSXIdentifier という別の種類のノードです。大文字・小文字・ドット付きのタグを並べたファイルでも確かめました。 // Main.jsx import { App } from "./App.jsx"; export const page = <App name="World" />; export const tag = <app name="World" />; export const member = <ui.Button />; --- page JSXElement JSXOpeningElement JSXIdentifier "App" JSXAttribute JSXIdentifier "name" StringLiteral "World" --- tag JSXElement JSXOpeningElement JSXIdentifier "app" (略) --- member JSXElement JSXOpeningElement JSXMemberExpression JSXIdentifier "ui" JSXIdentifier "Button" Babel のパーサーでは、大文字の App も小文字の app も同じ JSXIdentifier でした。この時点ではまだ「HTML の要素か、自作のコンポーネントか」を区別していません(Oxc のように、パースの時点で区別するパーサーもあります)。 段階 2: 変換 — JSX が関数呼び出しになる App.jsx を Babel(@babel/preset-react、automatic runtime)で変換し、dist-jsx/App.js に書き出しました。 import { useState } from "react"; import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime"; export function App({ name }) { const [count, setCount] = useState(0); return /#PURE/_jsxs(_Fragment, { children: [/#PURE/_jsxs("h1", { className: "title", children: ["Hello, ", name, "!"] }), /#PURE/_jsxs("button", { onClick: () => setCount(count + 1), children: ["count is ", count] }), [1, 2].map(n => /#PURE/_jsx("li", { children: n }, n))] }); } タグが _jsxs("h1", { className: "title", children: [...] }) という関数呼び出しに書き換わりました。 2 行目の import は、ソースには書いていません。呼び出す関数(react/jsx-runtime の jsx / jsxs)がどこから来るかを書かないと動かないので、変換ツールが自分で差し込んだものです。_jsx は、その jsx を別名で import したものです。/#PURE/ は「戻り値を使っていなければ消してよい」というバンドラ向けの注釈(PURE 注釈)です。 出力には、ほかにも決まりがあります。 属性と子は 1 つのオブジェクト(props)にまとめられ、子は props.children に入る 改行を含む空白だけのテキストを除いて、ソースに書いた子が複数なら _jsxs、1 つ以下なら _jsx になる key は props から外れて第 3 引数になる(_jsx("li", { children: n }, n)。例外もありますが、ここでは扱いません) 大文字のタグは変数、小文字のタグは文字列 Babel のパーサーでは区別されていなかった大文字と小文字は、変換の段階で分かれます。Main.jsx の変換結果です。 import { App } from "./App.jsx"; import { jsx as _jsx } from "react/jsx-runtime"; export const page = /#PURE/_jsx(App, { name: "World" }); export const tag = /#PURE/_jsx("app", { name: "World" }); export const member = /#PURE/_jsx(ui.Button, {}); 大文字で始まる App は変数 App の参照に、小文字の app は文字列 "app" に、ドット付きの ui.Button はプロパティの参照になりました。コンポーネント名を大文字で始めなければいけないのは、このルールで HTML の要素名(文字列)と区別されるからです。 5 つのツールで変換して比べる 実際のプロジェクトで JSX を変換しているのは、Babel だけではありません。Next.js は既定で SWC を使い、Vite 8 では Vite 本体の Oxc が JSX を変換していて、@vitejs/plugin-react v6 は Babel への依存をなくしました。そこで、同じ App.jsx を Babel・SWC・esbuild・Oxc・tsc の 5 つで変換しました。設定は 3 つそろえています。automatic runtime、importSource は react、開発用の出力(development)はオフです。 生の出力は見た目がかなり違います。たとえば esbuild はこうです。 import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { useState } from "react"; function App({ name }) { const [count, setCount] = useState(0); return /* @PURE */ jsxs(Fragment, { children: [ /* @PURE */ jsxs("h1", { className: "title", children: [ "Hello, ", name, "!" ] }), /* @PURE */ jsxs("button", { onClick: () => setCount(count + 1), children: [ "count is ", count ] }), [1, 2].map((n) => /* @PURE */ jsx("li", { children: n }, n)) ] }); } export { App }; import の順番、_jsx か jsx かという名前、PURE 注釈の有無と書き方、整形、export の形がツールごとに違います。そこで import 文と PURE 注釈を消し、名前の先頭の _ と export の形をそろえ、整形し直してから比べるスクリプトを書きました。消した import 文も、import 元は 5 つとも react/jsx-runtime で、違うのは並び順と別名だけでした。 App: 1 distinct normalized output(s) [tsc, babel, swc, esbuild, oxc] function App({name}){const[count,setCount]=useState(0);return jsxs(Fragment,{children:[jsxs("h1",{className:"title",children:["Hello, ",name,"!"]}),jsxs("button",{onClick:()=>setCount(count+1),children:["count is ",count]}),[1,2].map(n=>jsx("li",{children:n},n))]})} 5 つの出力は、書き方の差を除くと完全に一致しました。Main.jsx でも同じで、5 つのツールすべてが大文字のタグを変数、小文字のタグを文字列に分けていました。ui はどこにも定義していませんが、どのツールもそのまま変換しています。変換ツールは、名前の正体を調べていません。 実装は 5 つともまったく別物で、言語も JavaScript(Babel)・Rust(SWC・Oxc)・Go(esbuild・tsc)とバラバラです。それでも出力がそろうのは、関数の形(jsx(type, props, key))と、そこへの渡し方(子は props.children に、key は第 3 引数に、子が複数なら jsxs)までが React の決めた約束で、どのツールもそれに合わせて書き換えているからです。変換ツールはその約束どおりに呼び出しを書けばよく、他のファイルを見る必要がありません。 なお、開発用の出力をオンにすると、同じ正規化でも 4 通りに分かれました。tsc・SWC・esbuild・Oxc はデバッグ用のソースの位置(ファイル名・行・列)を同じ値で渡しますが、ファイル名を変数に入れるか(tsc は const、Oxc は var)直接書くか(SWC・esbuild)が違い、Babel 8 は位置の情報そのものを渡しません。 ブラウザに届く JavaScript を確かめる この形のままブラウザに届くことを、実際のプロジェクトでも確かめました。同じ App.jsx を Vite 8 のプロジェクトに置き、vite build の出力から App の部分を抜き出しました。Vite 8 の変換は、先ほどの 5 つのうちの Oxc です。 return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(h1,{className:title,children:[Hello, ,e,!]}),(0,p.jsxs)(button,{onClick:()=>n(t+1),children:[count is ,t]}),[1,2].map(e=>(0,p.jsx)(li,{children:e},e))]}) minify(圧縮)で変数名が縮み、文字列の引用符もバッククォートになっています。p はバンドルに取り込まれた react/jsx-runtime を指す変数で、(0,p.jsxs)(...) は this を渡さずに p.jsxs を呼ぶための、バンドラの書き方です。形は Babel の出力と同じ jsxs("h1", { className: "title", children: [...] }) で、出力の中に <h1 という文字列は 1 つもありませんでした。 開発サーバー(vite)でも確かめました。Chrome が App.jsx を要求すると、Content-Type: text/javascript の JavaScript が返ってきます。ブラウザはモジュールとして読み込むファイルの種類を拡張子ではなく Content-Type で判断するので、名前が .jsx のままでも JavaScript として実行します。中身は開発用の _jsxDEV(...)(react/jsx-dev-runtime)の呼び出しでしたが、タグが残っていない点は同じでした。あわせて、import { useState } from "react" も、/node_modules/.vite/deps/react.js?v=… からの import と const useState = …["useState"] という形に書き換わっていました。react の npm パッケージは CommonJS で配布されていてブラウザではそのまま動かないので、Vite が事前に ESM へ変換しておいたファイルです。 ブラウザに届いているのは、タグが消えた関数呼び出しの JavaScript でした。これが 1 つ目の疑問の残り半分の答えです。 段階 3: ランタイム — jsx() はただのオブジェクトを返す では、jsx() は何を返すのでしょうか。変換後の App.js と同じ呼び方で react/jsx-runtime の jsx / jsxs を呼び、戻り値を出力しました(jsx は本来アプリから直接呼ぶ関数ではなく、ここでは観察のために呼んでいます。NODE_ENV=production での結果です)。 --- jsxs("h1", ...) { '$$typeof': Symbol(react.transitional.element), type: 'h1', key: null, ref: null, props: { className: 'title', children: [ 'Hello, ', 'World', '!' ] } } 返ってきたのは、ただのオブジェクトでした。これが React Element です。type にはタグ名の文字列 'h1'、props には属性と子がそのまま入っています。$$typeof の値 Symbol(react.transitional.element) は、このオブジェクトが React Element であることを示す印です。段階 2 で JSX は関数呼び出しになりましたが、その関数がやっているのは「この形のオブジェクトを作る」ことだけです。DOM の要素はまだどこにも作られていません。 コンポーネントでも同じです。App を、呼び出された回数を数える関数 Counted で包んで jsx() に渡すと、type に関数そのものが入ったオブジェクトが返ります。 --- jsx(Counted, { name }) { '$$typeof': Symbol(react.transitional.element), type: [Function: Counted], key: null, ref: null, props: { name: 'World' } } type is the function itself: true | component called: 0 この時点で Counted は 1 回も呼ばれていませんでした。<App /> と書いても、App() が実行されるわけではありません。「App という関数を、この props で呼んでほしい」と書いたオブジェクトができるだけです。いつ呼ぶか(呼ばないか)はレンダラーが決めます。 結果 最後に、Vite の開発サーバーで開いた Chrome のページで、react-dom が組み立てた DOM を見ました。ページ上で document.getElementById("root").innerHTML を評価し、#root の中身を文字列にして取り出したものです。 <h1 class="title">Hello, World!</h1><button>count is 0</button><li>1</li><li>2</li> ここで初めて、画面の要素(DOM)が出てきました。ブラウザでは HTML の文字列を作って流し込んでいるのではなく、react-dom が React Element をもとに DOM を直接組み立てています。className は DOM では class 属性になっています。className は DOM の要素が持つプロパティ名(element.className)に合わせた名前で、class 属性として反映するのはレンダラーの仕事です。 ここまでをまとめると、次のとおりです。 JSX は ECMAScript の構文ではなく、Node.js も Chrome もタグの 1 文字目で SyntaxError を出した(段階 0) Babel のパーサーは、タグを JSXElement・JSXText などのノードにした。大文字のタグも小文字のタグも同じ JSXIdentifier だった(段階 1) JSX は _jsx / _jsxs の呼び出しになり、呼び出し先(react/jsx-runtime)の import が自動で差し込まれた。大文字のタグは変数、小文字のタグは文字列になり、key は props から外れて第 3 引数になった(段階 2) 設定をそろえた 5 つの変換ツールの出力は、書き方の差を除いて一致した(段階 2) Vite のビルド出力にも開発サーバーの応答にも、タグは残っていなかった(段階 2) jsx() は $$typeof・type・key・ref・props を持つただのオブジェクトを返し、コンポーネント関数はこの時点で呼ばれていなかった(段階 3) DOM を組み立てるのは react-dom で、className は class 属性になった 学び JSX の変換は、設定が分かればファイル 1 枚で完結する。 呼び出し先(react/jsx-runtime)と呼び出しの形(jsx(type, props, key))がファイルの外で決まっているので、変換ツールは他のファイルを見ずに書き換えられる。だから開発サーバーは、ブラウザに要求されたファイルだけをその場で変換して返せる 変換後の JSX を実行すると、「何を描画してほしいか」を書いたただのオブジェクトができる。 コンポーネントを呼ぶのも DOM を作るのも、そのオブジェクトを受け取ったレンダラーの仕事 課題に挙げた 2 つの疑問に答えると、こうなります。 「ブラウザは JSX を HTML として読んでいるのか、JavaScript として読んでいるのか」 — タグのままでは、HTML としても JavaScript としても読めません(段階 0)。タグはブラウザに届く前に関数呼び出しへ置き換わっていて、ブラウザはそれを普通の JavaScript として実行します。画面の要素(DOM)は、その実行の結果としてレンダラーが組み立てたものです。 「なぜスクリプト言語の JavaScript なのにビルドが要るのか」 — 書いたファイルが、ブラウザがそのまま実行できる形になっていないからです。その代表が JSX で、JavaScript ではありません。開発サーバーは JSX だけでなく、from "react" のような名前だけの import も、CommonJS で配布されている react を ESM に変換したファイルの URL に書き換えていました。開発中はこの書き換えを開発サーバーがその場でしてくれますが、静的ファイルを配るだけのデプロイ先には、それをしてくれる仕組みがありません。だから、デプロイ前のビルドで済ませておきます。 JSX の挙動で迷ったときは、DevTools の Network タブで届いた App.jsx を開くなどして、変換後の JavaScript を一度のぞいてみるところから始めていきたいですね。 コラム: TSX の場合 — tsx → jsx → js なのか、tsx → ts → js なのか ここまでは .jsx で見てきましたが、TypeScript と組み合わせて .tsx で書くプロジェクトも多くあります。.tsx には型と JSX の 2 つが入っているので、JavaScript になるまでに「型を消す」と「JSX を変換する」の 2 つの変換が要ります。題材の App.tsx は、App.jsx に型を 2 か所足しただけのものです。 type Props = { name: string }; export function App({ name }: Props) { // (以下 App.jsx と同じ) 結論から言うと、どちらの順でもできて、結果は同じでした。automatic runtime では、2 つの変換は互いに独立しているからです(classic runtime では、型を消すときに使われていない import を消す処理が import React を消してしまうことがあり、完全には独立していません)。 まず tsx → jsx → js です。tsc の jsx: preserve は、App.tsx から型を消し、JSX は残したまま App.jsx を出します。 // tsc --jsx preserve の出力(App.jsx) export function App({ name }) { const [count, setCount] = useState(0); return (<> <h1 className="title">Hello, {name}!</h1> (略) これを Babel で変換すれば JavaScript になります。 もう一方の順番の tsx → ts → js も作れます。Babel に TypeScript の構文プラグイン(@babel/plugin-syntax-typescript。構文を読むだけで、型は消さない)を付けて JSX の変換をかけると、型が残ったまま JSX が関数呼び出しになりました。 // Babel(preset-react + TypeScript の構文プラグイン)の出力。型はまだ残っている type Props = { name: string; }; export function App({ name }: Props) { const [count, setCount] = useState(0); return /#PURE/_jsxs(_Fragment, { (略) これを esbuild で型を消して JavaScript にしました。2 つの経路の最終出力を、本文と同じスクリプトで直接変換の結果と比べると、すべて一致しました(出力の見出しは読みやすく書き換えています)。 App: 1 distinct normalized output(s) [直接(tsc), 直接(babel), tsx→ts→js, tsx→jsx→js, 直接(oxc)] TypeScript 7 の実装(typescript-go の typescript/v7.0.2 タグの internal/compiler/emitter.go)で、tsc の変換器(tsc の中で 1 つの変換を受け持つ部品)を並べている getScriptTransformers を見ると、型を消す変換器が先で、JSX の変換器が後でした。 // transform TypeScript syntax { // (中略) // erase types tx = append(tx, tstransforms.NewTypeEraserTransformer(&opts)) // (中略) } if jsxTransformEnabled { tx = append(tx, jsxtransforms.NewJSXTransformer(&opts)) } つまり tsc は tsx → jsx → js の順で、jsx: preserve は、この並びから JSX の変換器だけを外した姿です。ただし中間のファイルはできず、どの変換器も前の変換器が返した AST を受け取り、次の AST を返していくだけです。他のツールも中間のファイルは作りませんが、作りはツールごとに違います。たとえば esbuild は型注釈をパースの時点で読み飛ばすので、そもそも型が AST に残りません。 .tsx で差が出るのは、変換の順番よりも、パーサーの読み方と型検査のほうです。tsc は型を検査するために、import を辿ってコンパイル対象のファイル一式(Program)を集め、名前の正体を解決し、型を計算します。 .tsx という拡張子は、TypeScript のパーサーの読み方を切り替える。.ts では型アサーションとして通る <string>v が、.tsx では TS17008: JSX element 'string' has no corresponding closing tag になった。.tsx でジェネリックなアロー関数を <T,>(x: T) => x とカンマ付きで書くのはこのため tsc --traceResolution で見ると、ソースのどこにも書いていない react/jsx-runtime が、react より先に解決されていた。JSX の型を引くため tsc は @types/react の JSX 名前空間で JSX を検査する。h1 は JSX.IntrinsicElements という interface のプロパティとして解決され、className は HTMLAttributes のプロパティだった。class と書くと TS2322 … Property 'class' does not exist … Did you mean 'className'? になる(それでも JavaScript は出力される) 所要時間は全体で約 0.18 秒で、そのうち Check(型検査の工程)が約 0.16 秒、JSX の変換を含む書き出し(Emit)は 0.001 秒だった。--noCheck を付けると全体で 0.020 秒になる。React を含まない 1 行の .ts と比べると、React の型定義(@types/react の 3 ファイルと csstype)が Program に加わった分、計算された型の数が約 2 倍になっていた。この題材は skipLibCheck を付けていないので、増えた分のほとんどは JSX ではなく型定義ファイル自体の検査だ 変換はファイル 1 枚で終わるのに、検査は呼び出し先の型定義まで Program を広げないとできません。.tsx の JSX は、この 2 つの仕事の重さの差がはっきり見える場所でした。 コラム: React 以外の JSX JSX は Preact・Hono・Vue・Solid でも書けます。構文と AST(段階 0・1)はどのフレームワークでも共通で、違いが出るのは「何の関数を呼ぶか」(段階 2)と「その関数が何を返すか」(段階 3)です。 ! 以下は各フレームワークのドキュメントに基づく整理で、この記事では検証していません。 フレームワーク 変換のしかた(呼び出し先) 返すもの React react/jsx-runtime React Element(ただのオブジェクト) Preact preact/jsx-runtime VNode Hono hono/jsx/jsx-runtime HTML 文字列にできるノード Vue 3 専用の Babel プラグインが生成する関数呼び出し VNode Solid 専用のコンパイラが生成する DOM 操作のコード 実際の DOM ノード(ブラウザ向けの出力) React・Preact・Hono は、jsx-runtime という同じ形の約束の上で返すものだけを差し替えているので、変換ツールの呼び出し先の設定(importSource)を変えるだけで切り替わります。Vue にも vue/jsx-runtime はありますが、公式が案内しているのは専用の Babel プラグインです。Solid はこの約束を使わず、JSX を、DOM を直接組み立てるコードにコンパイルします。 参考 JSX の仕様草案: react.github.io React「Writing Markup with JSX」(className の由来): react.dev React ブログ「Introducing the New JSX Transform」(automatic runtime): legacy.reactjs.org Next.js Compiler(SWC): nextjs.org @vitejs/plugin-react の CHANGELOG(v6 で Babel への依存を削除): github.com/vitejs/vite-plugin-react/blob/main/pac… Oxc: oxc-project/oxc esbuild の設計(型注釈の読み飛ばし): github.com/evanw/esbuild/blob/main/docs/architect… typescript-go internal/compiler/emitter.go(v7.0.2): github.com/microsoft/typescript-go/blob/typescrip… Preact: preactjs.com Hono の JSX: hono.dev Vue「Render Functions & JSX」: vuejs.org Solid の JSX コンパイラ(dom-expressions): ryansolid/dom-expressions

  5. u know i completely forgot i ever wrote this comment. what the hell TypeScript#33304

    6 likes
  6. Would love everyone's opinion on microsoft/WindowsDeveloperConfig

    82 likes · 8 reposts · 6,675 views
  7. Reverse Engineering Block Blast Block Blast looks like a puzzle game. A decompile of the app suggests it's closer to a per-player ad pricing engine with a puzzle attached. Three tree-based models run on your phone, a bandit experiment tunes when you lose, and a rule decides your next three pieces based on what ad is sitting in memory. The Problem It's Solving The game is free and has no ad-free purchase, so revenue depends on rewarded and full-screen ads. Sensor Tower estimates put its ad revenue at roughly $127 million for January to May 2026, ahead of Candy Crush Saga at $81.1 million. Ad value varies a lot per player (country, device, history), and the best moment to show a rewarded ad is right after a loss. Making that work needs per-player prediction, per-deal control of the pieces, and the ability to change both without shipping an app update. How the System Is Built The research is Ayo Omolewa's breakdown of Android 10.8.2 and iOS 7.4.9, using jadx and Ghidra. The store APK holds very little. Logic ships as "traits" (modules with variants called arms), and at launch the server tells the app which arm of which trait you get. His config named about 700 traits, selected 254, and 101 were fetched after install as XXTEA-encrypted, Brotli-compressed JavaScript. Two players can run different games, and the studio can change yours silently. The Models | Model | Size and inputs | What it decides | |---|---|---| | XGBoost regression (xgboost_regression_model111.json) | 59 trees, depth up to 8, 27 inputs (18 about ads) | finalEcpm: your estimated ad value | | XGBoost classifier (predict_travel_difficulty_dead) | 500 trees, 52 inputs | Where in a level the lethal puzzle lands | | LightGBM | 1,000 trees, 93 inputs | Whether you'll be less active tomorrow | The ad value model. The inputs are mostly money-related: prices of ads loaded today and yesterday, country, phone model, RAM, install date, and how your first game went. The trees lean hardest on first score, latest ad price, RAM, phone model and country. The inference code is a plain loop: start each tree at the root, go left or right on a feature threshold (missing values follow a default direction), add the leaf weight to a running sum starting at the base score. Omolewa's port reproduces the game's outputs to the last decimal. Changing one input on a made-up US player on an iPhone 15 gives: | Change | Ad value (eCPM) | |---|---| | Baseline (US, first score 1,000) | 25.48 | | Brazil | 8.08 | | India | 5.59 | | First score 500 / 2,000 / 10,000 | 25.79 / 21.12 / 20.34 | The same US baseline on Android scores 48.96. The output feeds other rules. One compares your rewarded and full-screen prices and, if rewarded is worth at least twice full-screen in the shipped version, grants an extra revive (which plays a rewarded ad). Others add a full-screen ad when your price is high or skip full-screen ads when you're worth almost nothing. The "where do you lose" model. The game scores 12 candidate options (4 values of a sw_process setting times 3 difficulty levels) and keeps the argmax. Inputs are mostly about your history: current level, attempts, games finished this week, time since install. The winning sw_process maps to a stretch of the level (first 30%, 30 to 80%, last 20%). On reaching it, players who usually accept revives (above 75%) get an extra one, and from the fourth deal after that the game requests the lethal puzzle. Other rules read the same pick the opposite way and make the level easier when it lands on the fourth option. The churn model. If the LightGBM score is 0.69 or higher, a pink revive button replaces the normal one and skips the ad, once a day. It leans on app age, high score, RAM and average score. Server-side models. Rules also call models named for churn, LTV, revive-click and xDeepFM. Those weights never reach the phone, so the only visible part is the request. One call to /v1/ecpm_prediction sends 40 fields, including carrier, storage, hour of day and recent ad prices. The Rules That Act on the Predictions These are hand-written, not learned. RewardHighValueAdHarvestTrait fires when you finished your last three rewarded ads, the ad currently loaded is worth at least 3.5 times your last one (read from AppLovin MAX eCPM), and you're 1,000 points past your high score (500 or 750 in other arms). It then requests generator ZHI_SI_TI. The generator picks two pieces that fit and one that doesn't, searches every order and placement including line clears, and keeps the set only if nothing works. The code labels the pieces "lethal puzzle" in Chinese. PersonalMarginBreakTrait gives every deal a 20% chance of the same hand once you're 10% past your record. MultiClearBoostThenKillTrait sends your user ID to two server endpoints, and for the tiers labelled "not sensitive to being forced to die," waits for a big clear, then requests the lethal puzzle a few rounds later once the game reaches roughly your usual length. FastHandPunishTrait asks for hard pieces when your last six sets averaged under 4.2 seconds and you're past 93% of your high score. MaturityDevelopmentV2Trait scores habit, skill and ad history (10.98, 14.66 and 19.27 in the live test), and when the total (44.91) is under 65 it swaps hard puzzles for easy fills. AdPlusMinusStrategyTrait adds a random bonus of up to 10% of your high score after one type of revive. MABXiBaiTrait is a six-arm experiment on how soon the lethal puzzle may be requested: never, or after 4, 6, 10, about 17 or 30 minutes. Per arm it logs whether you started a new game within 15 minutes and the share of revive offers you accepted. Why This Is a Bigger Deal Than It Looks The ML itself is cheap: tree ensembles walked in a loop over JSON, no GPU, runs on a low-end phone and offline. The engineering is the delivery layer. Server-assigned arms, encrypted hot-loaded JavaScript and per-player A/B tests make this a feature-flag platform with bandit tuning, which is why it can be changed daily. Because the lethal-puzzle rule needs a rewarded ad loaded, it can't fire offline or with a phone-wide DNS blocker, while ad-independent rules keep running. Apple permits JavaScript updates that don't change what the app is. Whether this qualifies is Apple's call. The usual caveat applies: this is one researcher's analysis. mobilegamer.biz reported no reply from Hungry Studio, and TechRadar noted that independent verification matters. The evidence bundles (decoded rules, test scripts, hashes) are public at Ayoships if you want to run the checks yourself. Availability and Access The game is on Google Play and iOS. The decryption key and the steps for getting past the apps' protection aren't published. If a free puzzle game ships three on-device models and a bandit experiment, the real question for developers isn't whether consumer apps use ML. It's how much of their behavior now lives in a config server instead of the binary. Follow for more coverage on MCP, agentic AI, and AI infrastructure. Inspired to write this by @StompnWorldfan's video on YouTube: watch it here.

    7 reactions
  8. Reddit · · r/BestGitHubRepos · u/Artilas_Digital · microsoft/mcp-for-beginners

    MCP for Beginners: Learn MCP with Hands-on Code Examples in C#, Java, JavaScript, Rust, Python, and TypeScript (18k stars) What it does All text below is quoted directly from the project README. >This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration. Learning Objectives: - Understand MCP fundamentals: You'll grasp what the Model Context Protocol is and why it's revolutionizing how AI applications work together, using analogies and examples that make sense. - Build your first MCP server: You'll create a working MCP server in your preferred programming language, starting with simple examples and growing your skills step by step. - Connect AI models to real tools: You'll learn how to bridge the gap between AI models and actual services, giving your applications powerful new capabilities. - Implement security best practices: You'll understand how to keep your MCP implementations safe and secure, protecting both your applications and your users. - Deploy with confidence: You'll know how to take your MCP projects from development to production, with practical deployment strategies that work in the real world. - Join the MCP community: You'll become part of a growing community of developers who are shaping the future of AI application development. >git clone https://github.com/microsoft/mcp-for-beginners.git Repository microsoft/mcp-for-beginners Repository stats |Metric|Value| |:-|:-| |Stars|17,526| |Forks|5.7k| |Last release|None| |Languages|Jupyter Notebook 83.5%, TypeScript 5.5%, Python 5.3%| |Contributors|71| |AI contributor accounts (Claude / Codex / Cursor / Copilot)|@Copilot (159 commits), @claude (1 commits)| |AI co-authored commits|Claude: 1, Copilot: 119| Main contributor |Field|Value| |:-|:-| |Name|Minseok Song| |GitHub|@skytin1004| |Commits to this repo|842 (top contributor)| |Bio|Microsoft MVP (Microsoft Foundry) OSS Maintainer: Co-op Translator| |Followers|564| ────────────────────────────── 📌 How many great GitHub repos have you discovered and completely forgotten about? Don't let another useful tool disappear into your Reddit feed. Get the community's best repos, organized by category, plus key takeaways from real developer discussions, delivered to your inbox twice a week. 📬 Never lose track of great repos again. Subscribe free.

    45 points
  9. Reddit · · r/BestGitHubRepos · u/amootiranian · microsoft/ai-agents-for-beginners

    AI Agents for Beginners: 18 Lessons to Get Started Building AI Agents (78k stars) What it does All text below is quoted directly from the project README. >18 Lessons to Get Started Building AI Agents Lessons: - Intro to AI Agents and Agent Use Cases - Tool Use Design Pattern - Agentic RAG - Multi-Agent Design Pattern - Using Agentic Protocols (MCP, A2A and NLWeb) - Context Engineering for AI Agents - Building Computer Use Agents (CUA) - Securing AI Agents >This course has lessons covering the fundamentals of building AI Agents. Each lesson covers its own topic so start wherever you like! Repository microsoft/ai-agents-for-beginners Repository stats |Metric|Value| |:-|:-| |Stars|78,027| |Forks|25.6k| |Last release|None| |Languages|Jupyter Notebook 99.7%, Other 0.3%| |Contributors|111| |AI contributor accounts (Claude / Codex / Cursor / Copilot)|@Copilot (96 commits), @claude (6 commits)| |AI co-authored commits|Claude: 6, Copilot: 60| Main contributor |Field|Value| |:-|:-| |Name|Minseok Song| |GitHub|@skytin1004| |Commits to this repo|573 (top contributor)| |Bio|Microsoft MVP (Microsoft Foundry) OSS Maintainer: Co-op Translator| |Followers|564| ────────────────────────────── 📌 How many great GitHub repos have you discovered and completely forgotten about? Don't let another useful tool disappear into your Reddit feed. Get the community's best repos, organized by category, plus key takeaways from real developer discussions, delivered to your inbox twice a week. 📬 Never lose track of great repos again. Subscribe free.

    438 points
  10. Microsoft.UI.Reactorを触ってみる :::note warn ReactあるいはReact Nativeを少しでも触ったことのある人向けに書いています。 ::: Microsoftから新しいフレームワークが発表されました。 devblogs.microsoft.com > Reactor is not a new UI platform. Windows FormsやWPF、UWPなどに続くものではないようです。 とりあえず動かしたい人は.NET SDK 10.0.100以降があれば簡単にサンプルアプリを動かすことができます。以下のファイルを作成して #:package Microsoft.UI.Reactor@0.1.0-preview.16 #:property OutputType=WinExe #:property TargetFramework=net10.0-windows10.0.22621.0 #:property UseWinUI=true using Microsoft.UI.Reactor; using Microsoft.UI.Reactor.Core; using static Microsoft.UI.Reactor.Factories; ReactorApp.Run<MyApp>("Hello Reactor", width: 340, height: 200); class MyApp : Component { public override Element Render() { var (count, setCount) = UseState(0); return VStack( TitleBar("Hello Reactor"), VStack(12, Heading($"Count: {count}"), HStack(8, Button("-", () => setCount(count - 1)), Button("+", () => setCount(count + 1)) .AccentButton() ) ).Padding(24) ).Backdrop(BackdropKind.Mica); } } dotnet runコマンドを実行するだけでサンプルアプリケーションが起動しました。 dotnet run HelloReactor.cs --arch x64 !hello-reactor.png C#やWinUIが分からないモバイルアプリエンジニアでもソースコードを見れば「React Nativeとほぼ同じだ」と気づくのではないでしょうか。Reactorが描画するのはWinUI3のコンポーネントのようですね。 「使えるUIコンポーネントは何か?」「useEffectやuseMemoもあるのか?」という疑問に答えてくれるサンプルアプリケーションもありました。ReactorGalleryというアプリケーションです。 microsoft/microsoft-ui-reactor このリポジトリにはReactorGallery以外にも様々なサンプルアプリケーション(プロジェクト)があって、 - WinFormsInterop(Windows Formsの中にReactorを組み込む) - ReactorCharting.Gallery(D3.jsを使ったグラフ描画) - NavigationDemo あたりが実務で参考になると思います。Reactor.AnalyzersやReactor.Devtoolsなどのプロジェクトも含まれており、ESLintやReact Developer Toolsに近いエコシステムも整備されつつあるようです。 ReactorGalleryは以下の手順でビルドできました。 git clone https://github.com/microsoft/microsoft-ui-reactor.git cd microsoft-ui-reactor dotnet build samples/ReactorGallery/ReactorGallery.csproj -p:Platform=x64 !reactor-gallery-home.png 実際のコンポーネントとサンプルコードがセットになっています。 チュートリアルやAPIリファレンスなどの詳しい情報は公式ドキュメントを参照してください。

Trending awards, every completed day and week
Gold
2791st place finishes
Silver
2872nd place finishes
Bronze
3213rd place finishes
Awarded repositories
103Owned by Microsoft now

Repositories

Ordered by gold, then silver, then bronze.

  1. generative-ai-for-beginnersBest: 1st by forks, 3,366 forks332935
  2. winget-pkgsBest: 1st by PR authors, 685 PR authors3190132
  3. ML-For-BeginnersBest: 1st by stars, 5,211 stars251413
  4. Web-Dev-For-BeginnersBest: 1st by stars, 2,783 stars181311
  5. MS-DOSBest: 1st by stars, 4,923 stars1482
  6. markitdownBest: 1st by stars, 16,730 stars12116
  7. calculatorBest: 1st by stars, 10,413 stars1044
  8. terminalBest: 1st by stars, 32,014 stars9104
  9. BitNetBest: 1st by stars, 4,562 stars720
  10. visual-chatgptBest: 1st by stars, 13,309 stars625
  11. OmniParserBest: 1st by stars, 8,088 stars623
  12. vscodeBest: 1st by stars, 6,883 stars602
  13. c9-python-getting-startedBest: 1st by stars, 820 stars550
  14. typescript-goBest: 1st by stars, 15,248 stars500
  15. IoT-For-BeginnersBest: 1st by stars, 4,733 stars440
  16. autogenBest: 1st by stars, 3,238 stars431
  17. graphragBest: 1st by stars, 6,732 stars430
  18. CNTKBest: 1st by stars, 1,664 stars421
  19. winfileBest: 1st by stars, 3,700 stars412
  20. winget-cliBest: 1st by stars, 4,809 stars410
  21. WinObjCBest: 1st by stars, 3,392 stars410
  22. WSLBest: 1st by stars, 7,755 stars410
  23. ChakraCoreBest: 1st by stars, 4,104 stars401
  24. fluentui-emojiBest: 1st by stars, 3,931 stars400
  25. Data-Science-For-BeginnersBest: 1st by stars, 517 stars344
  26. playwrightBest: 1st by stars, 5,761 stars332
  27. VibeVoiceBest: 1st by stars, 749 stars325
  28. cascadia-codeBest: 1st by stars, 553 stars240
  29. inshellisenseBest: 1st by stars, 5,882 stars221
  30. reactxpBest: 1st by stars, 1,499 stars221
  31. windows-rsBest: 1st by stars, 695 stars221
  32. playwright-mcpBest: 1st by stars, 1,396 stars220
  33. ai-eduBest: 1st by stars, 568 stars202
  34. TypeScriptBest: 1st by stars, 453 stars202
  35. everyonecancodeBest: 1st by forks, 249 forks201
  36. STLBest: 1st by stars, 1,804 stars201
  37. GW-BASICBest: 1st by stars, 1,271 stars200
  38. PowerToysBest: 1st by stars, 675 stars1412
  39. napajsBest: 1st by stars, 1,886 stars141
  40. frontend-bootcampBest: 1st by stars, 1,659 stars123
  41. garnetBest: 1st by stars, 1,518 stars120
  42. AI-For-BeginnersBest: 1st by stars, 9 stars113
  43. FASTERBest: 1st by stars, 628 stars110
  44. magentic-uiBest: 1st by stars, 653 stars110
  45. mimallocBest: 1st by stars, 640 stars110
  46. msbuildBest: 1st by stars, 861 stars110
  47. qdkBest: 1st by forks, 64 forks110
  48. WSL2-Linux-KernelBest: 1st by stars, 1,099 stars110
  49. dotnetBest: 1st by PR authors, 24 PR authors106
  50. ailabBest: 1st by stars, 788 stars103
  51. azuredatastudioBest: 1st by stars, 791 stars101
  52. codetourBest: 1st by stars, 386 stars101
  53. fluentui-system-iconsBest: 1st by stars, 726 stars101
  54. Microsoft-3D-Movie-MakerBest: 1st by stars, 1,460 stars101
  55. FluidFrameworkBest: 1st by stars, 799 stars100
  56. nodeBest: 1st by stars, 403 stars100
  57. ProcDump-for-LinuxBest: 1st by stars, 594 stars100
  58. ProcMon-LinuxBest: 1st by stars, 768 stars100
  59. service-fabricBest: 1st by stars, 887 stars100
  60. wslgBest: 1st by stars, 632 stars100
  61. api-guidelinesBest: 2nd by stars, 1,511 stars040
  62. azurechatBest: 2nd by stars, 1,066 stars033
  63. DeepSpeedBest: 2nd by stars, 3,576 stars033
  64. editBest: 2nd by stars, 2,553 stars031
  65. BosqueLanguageBest: 2nd by stars, 702 stars021
  66. promptbaseBest: 2nd by stars, 755 stars021
  67. SPTAGBest: 2nd by stars, 1,104 stars021
  68. ai-agents-for-beginnersBest: 2nd by forks, 129 forks015
  69. promptflowBest: 2nd by stars, 838 stars012
  70. qlibBest: 2nd by forks, 130 forks012
  71. TRELLISBest: 2nd by stars, 532 stars012
  72. TypeChatBest: 2nd by stars, 554 stars012
  73. agent-frameworkBest: 2nd by stars, 372 stars011
  74. AirSimBest: 2nd by stars, 372 stars011
  75. fastBest: 2nd by stars, 329 stars011
  76. vscode-copilot-chatBest: 2nd by stars, 1,017 stars011
  77. data-formulatorBest: 2nd by stars, 1,258 stars010
  78. ELLBest: 2nd by stars, 348 stars010
  79. malmoBest: 2nd by stars, 431 stars010
  80. monaco-editorBest: 2nd by stars, 881 stars010
  81. openvmmBest: 2nd by stars, 622 stars010
  82. Power-FxBest: 2nd by stars, 599 stars010
  83. prompt-engineBest: 2nd by stars, 719 stars010
  84. pyrightBest: 2nd by stars, 974 stars010
  85. RustTrainingBest: 2nd by stars, 377 stars010
  86. SandDanceBest: 2nd by stars, 445 stars010
  87. StudentsAtBuildBest: 2nd by PR authors, 142 PR authors010
  88. veronaBest: 2nd by stars, 598 stars010
  89. VFSForGitBest: 2nd by stars, 759 stars010
  90. JARVISBest: 3rd by stars, 2,406 stars005
  91. BASIC-M6502Best: 3rd by stars, 427 stars002
  92. ethrBest: 3rd by stars, 1,765 stars002
  93. ApplicationInspectorBest: 3rd by stars, 612 stars001
  94. BlingFireBest: 3rd by stars, 735 stars001
  95. checkedcBest: 3rd by stars, 436 stars001
  96. computervision-recipesBest: 3rd by stars, 481 stars001
  97. faraBest: 3rd by stars, 290 stars001
  98. join-dev-designBest: 3rd by PR authors, 42 PR authors001
  99. Mastering-GitHub-Copilot-for-Paired-ProgrammingBest: 3rd by stars, 791 stars001
  100. msquicBest: 3rd by stars, 424 stars001
  101. pomlBest: 3rd by stars, 382 stars001
  102. sudoBest: 3rd by stars, 1,080 stars001
  103. TouchDevelopBest: 3rd by stars, 413 stars001

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.