npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ishibashi0112/webview2-bridge-gen

v0.5.0

Published

zod contract -> JSON Schema -> TypeScript types + VB.NET DTO / Interface / Dispatcher generator for WinForms (.NET Framework 4.8) + WebView2 + Vite/React apps

Readme

@ishibashi0112/webview2-bridge-gen

Code generator for webview2-bridge: write the contract between a Vite/React UI and a VB.NET WinForms (.NET Framework 4.8) host once, in zod, and generate both sides.

contract.ts (zod)  ──>  contract.schema.json  ──>  contract-types.ts   (TypeScript, for the UI)
                                               ├─>  Dto.vb / Interfaces.vb / Dispatcher.Generated.vb / Events.vb   (VB.NET)
                                               └─>  openapi.json   (OpenAPI 3.1, optional: the same contract served over HTTP)

The front-end runtime is @ishibashi0112/webview2-bridge-client; the VB.NET runtime is the NuGet package WebView2Bridge.Runtime (plus WebView2Bridge.WinForms for the host).

Install

pnpm add -D @ishibashi0112/webview2-bridge-gen zod

Requires Node.js 20.19+ and zod 4.

Start a new app

pnpm create webview2-bridge my-app --name MyInventory      # = pnpm dlx @ishibashi0112/webview2-bridge-gen init my-app --name MyInventory
cd my-app && pnpm install && pnpm gen:check

init writes a complete skeleton (32 files): the zod contract, a Vite + React app with a mock transport, and three VB.NET projects (<Name>.Contract netstandard2.0, <Name>.Impl net48, <Name>.Host WinForms net48) including the generated code and the bundled VB runtime. --name becomes the VB namespace / project names (PascalCase; defaults to the directory name). The generated README walks through the dev loop and the Windows checks.

Define the contract

// contract/contract.ts
import { z } from "zod";
import { defineContract } from "@ishibashi0112/webview2-bridge-gen";

// Give shared objects / enums a name with .meta({ id }) — it becomes the VB class name and the TS type name
const Part = z
  .object({ partNo: z.string(), name: z.string(), qty: z.number().int(), updatedAt: z.string() })
  .meta({ id: "Part" });

export const contract = defineContract({
  methods: {
    parts: {
      search: {
        input: z.object({ keyword: z.string().min(1), limit: z.number().int().optional() }),
        output: z.object({ items: z.array(Part) }),
      },
    },
  },
  events: {
    progress: z.object({ percent: z.number(), message: z.string().optional() }),
  },
});
export type Contract = typeof contract;

Configure and run

// webview2-bridge.gen.json (repository root)
{
  "contract": "contract/contract.ts",
  "schemaOut": "contract/contract.schema.json",
  "ts": { "outDir": "apps/web/src/generated", "contractImport": "@webview2-bridge/contract" },
  "vb": { "outDir": "dotnet/MyApp.Contract/Generated", "namespace": "MyApp.Contract" },
  "openapi": { "out": "contract/openapi.json" }   // optional
}
webview2-bridge-gen            # generate (uses ./webview2-bridge.gen.json)
webview2-bridge-gen --check    # CI: exit 1 if the generated files are out of date
webview2-bridge-gen --config path/to/config.json

Generated files start with an <auto-generated> header; the generator only overwrites / removes files carrying that header. Commit the generated files.

What is generated

TypeScript (contract-types.ts): PartsSearchInput / PartsSearchOutput, ProgressEvent, named types (Part), MethodMap / EventMap, methodNames / eventNames. Types are derived from the zod contract with z.input / z.output.

VB.NET (into Namespace Global.<namespace>, referencing the WebView2Bridge.Runtime NuGet package):

| File | Content | |---|---| | Dto.vb | one Public Class per object with <JsonProperty("camelCase")>; string enums as NotInheritable Class with Public Const | | Interfaces.vb | Public Interface IPartsApi with Function Search(req As PartsSearchRequest) As Task(Of PartsSearchResponse) | | Dispatcher.Generated.vb | DispatcherExtensions.Register(dispatcher, api) extension methods wiring "parts.search" to IPartsApi.Search | | Events.vb | BridgeEvents with Sub Progress(payload As ProgressEvent) emitting "event.progress" |

OpenAPI 3.1 (openapi.json, when openapi.out is set): the same contract as an HTTP API, so the VB host can later be replaced by any server without touching the UI (the client runtime's HttpTransport speaks this shape):

| Contract | HTTP | |---|---| | method parts.search | POST /parts/search, request body = input, 200 body = output (plain JSON, no JSON-RPC envelope) | | error | 400 (-32602 / -32600 / -32700), 404 (-32601), 500 (-32000 and other codes); body = JSON-RPC error object { code, message, data } | | events | GET /events as Server-Sent Events; each data: line is one JSON-RPC notification { "jsonrpc": "2.0", "method": "event.progress", "params": {...} } | | .meta({ id }) schemas, <Ns><Method>Request / Response, <Name>Event | components/schemas under the same names as the VB DTOs |

Options: title, version (of the contract, info), servers (default ["/"]), basePath (prefix for every path, default ""), eventsPath (default "/events", false to omit). Authentication is deliberately not part of the contract (security: []).

Type mapping: stringString, numberDouble, intInteger (.meta({ format: "int64" })Long), booleanBoolean, arrayList(Of T), recordDictionary(Of String, T), unknownJToken, X | null→nullable, optional value types→Nullable(Of T). Optional properties get NullValueHandling.Ignore so Nothing is omitted from JSON (zod .optional() rejects null). Unions, intersections, dates and bigints are rejected with a clear error.

Naming: .meta({ id }) wins; otherwise <Namespace><Method>Request / Response, <Event>Event, nested objects <Owner><Prop>, array items singularized (itemsItem).

VB runtime without NuGet

The VB.NET runtime (Dispatcher, JsonRpc, IBridgeEmitter) and the WinForms glue (WebViewBridge) are bundled in this package. Point vb.runtime.outDir / vb.winforms.outDir at your projects and the generator writes them as auto-generated files, so no custom NuGet package is needed — your Contract project only references Newtonsoft.Json and your Host only Microsoft.Web.WebView2.

"vb": {
  "outDir": "dotnet/MyApp.Contract/Generated",
  "namespace": "MyApp.Contract",
  "runtime":  { "outDir": "dotnet/MyApp.Contract/Runtime" },
  "winforms": { "outDir": "dotnet/MyApp.Host/Bridge" }
}

The files keep the namespaces WebView2Bridge.Runtime / WebView2Bridge.WinForms, so the code you write is identical whether the runtime comes from these files or from the NuGet packages of the same name. Upgrading the runtime = upgrading this npm package and running the generator again (--check reports outdated copies).

Options (vb)

| Option | Default | Meaning | |---|---|---| | namespace | required | namespace of the generated code | | runtimeNamespace | WebView2Bridge.Runtime | namespace of Dispatcher / IBridgeEmitter (NuGet WebView2Bridge.Runtime) | | dispatcherClass | Dispatcher | runtime dispatcher class name | | eventsClass | BridgeEvents | generated events helper class name | | emitterInterface | IBridgeEmitter | runtime emitter interface name | | runtime.outDir | — | write the bundled VB runtime (3 files) here; omit when using the NuGet package or a ProjectReference | | winforms.outDir | — | write the bundled WebViewBridge.vb here; omit when using the NuGet package or a ProjectReference |

Programmatic use

import { defineContract, toSchema, emitTs, emitVb } from "@ishibashi0112/webview2-bridge-gen";
import { generate, emitVbRuntime } from "@ishibashi0112/webview2-bridge-gen/generate"; // Node only (fs)

MIT