Install any skill in seconds. Free to start, no credit card required.
Get Started Free →dotnet/use-js-interop
Add, review, or fix JavaScript interop in Blazor components. USE FOR: calling JavaScript from Blazor, calling .NET from JavaScript, collocated .razor.js modules, IJSRuntime, IJSObjectReference lifecycle, DotNetObjectReference, ElementReference, timing rules for when JS is available, IAsyncDisposable disposal of JS references, server-side JS interop safety. DO NOT USE FOR: general Blazor component authoring without JS interop needs (use author-component), forms (use collect-user-input).
Passed 22 of 22 test cases with the skill, and 16 of 22 without it.
and 9 more in the full report
6 fixed16 passed either way0 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 6 test cases the skill fixed. Same model, same prompt, with and without the skill.
I have a Blazor Server component that connects to a JavaScript audio player, but it currently makes several back-and-forth calls every time the user adjusts volume or pauses playback. Please review my C# component and JavaScript code, then refactor both files to improve performance, clean up interop handling, and ensure proper lifecycle management.
| Checked | Without skill | With skill |
|---|---|---|
| The JavaScript code uses a collocated .razor.js module path instead of wwwroot. | Missed | Passed |
| The JavaScript invokeMethodAsync call is wrapped in a try catch block. | Missed | Passed |
| The JS callback uses a top-level const for the C# method name. | Missed | Passed |
The instructions your model reads when the skill loads.
Always use collocated .razor.js files with export — never global window.* functions or <script> tags.
// ChartPanel.razor.js — placed next to ChartPanel.razor
export function initialize(canvas, dotNetRef) { /* ... */ }
export function updateData(points) { /* ... */ }
export function dispose() { /* ... */ }
Import paths: same project = "./Components/ChartPanel.razor.js", RCL = "./_content/{AssemblyName}/...".
All JS interop must happen in OnAfterRenderAsync or event handlers — never in OnInitialized, OnParametersSet, or constructors. JS is not available during server prerendering.
Use a typed interop wrapper (see Section 4) — never call InvokeAsync/InvokeVoidAsync with raw string literals:
private ChartInterop? _chart;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_chart = new ChartInterop(JS);
await _chart.InitializeAsync(_canvasRef);
}
}
Parameter changes: set a flag in OnParametersSet, apply in OnAfterRenderAsync:
private bool _dataChanged;
protected override void OnParametersSet() => _dataChanged = true;
test cases passed, vs 16 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.