Call C# from JavaScript
A native contract is a C# class whose annotated methods become generated, typed TypeScript methods.
Define the native contract
Add GreetingModule.cs to the host project:
using Vidra.Bridge;
namespace MyApp;
public record GreetArgs(string Name);
public record GreetResult(string Message);
[BridgeModule("greeting")]
public sealed class GreetingModule : BridgeModuleBase
{
[BridgeMethod("greet")]
public Task<GreetResult> GreetAsync(
GreetArgs args,
CancellationToken ct)
{
return Task.FromResult(
new GreetResult($"Hello, {args.Name} from C#!"));
}
}
The contract name and method name become the generated JavaScript API. Argument and result records become TypeScript interfaces.
Register the module
Pass the module to UseVidra in MauiProgram.cs:
builder
.UseMauiApp<App>()
.UseVidra(dispatcher =>
{
dispatcher.Register(new GreetingModule());
});
Only registered modules can receive bridge calls.
Generate the TypeScript API
Build or run the app:
npm run dev
The host project already sets VidraTsOutputDir to ui/src/generated. The
build writes a generated greeting proxy and exports it from
ui/src/generated/index.ts.
Generated files begin with Auto-generated by vidra-codegen. Do not edit. Keep
them committed, but change the C# declaration rather than editing TypeScript
output.
Call C# from the UI
import { greeting } from "./generated/index.js";
const { message } = await greeting.greet({ name: "Ada" });
console.log(message);
The call is typed end to end:
- Omitting
nameis a TypeScript error. - The result is inferred as
{ message: string }. - Renaming the C# method or DTO changes generated output.
- A stale web/native contract fingerprint is rejected when the WebView starts.
Built-in native contracts
Vidra’s built-in APIs use the same contract model. They are generated into
@vidra-dev/sdk and do not need registration:
import { clipboard } from "@vidra-dev/sdk";
const { text } = await clipboard.getText();
See Built-in native capabilities for the complete reference, or continue with Call JavaScript from C#.