Generate Swift / Kotlin types
A native WebView host written in Swift or Kotlin cannot import a TypeScript contract directly. webview-bridge-kit-gen reads message names and payload / response types from the contract and generates native code.
The output includes DTOs, BridgeHandlers, runtime bindings, and type-safe event functions. See Using it in Swift or Using it in Kotlin for platform wiring.
Setup
The generator uses the TypeScript compiler API. typescript is an optional peer dependency, so install it in the project that runs the generator.
npm install webview-bridge-kit
npm install --save-dev typescriptBy default, the contract file must export a value named contract.
// bridge-contract.ts
import { command, defineContract, event, request } from 'webview-bridge-kit';
import { z } from 'zod';
export const contract = defineContract({
KAKAO_LOGIN: request({
response: z.object({
accessToken: z.string(),
expiresIn: z.number().optional(),
}),
}),
SEND_LOGS: command({ payload: z.object({ lines: z.array(z.string()) }) }),
OPEN_CAMERA: command(),
PHOTO_TAKEN: event({
payload: z.object({
uri: z.string(),
meta: z.object({ width: z.number(), height: z.number() }),
}),
}),
});This does not inspect the schema library's runtime objects. It reads the types TypeScript inferred into the __req, __res, and __payload phantom fields, so any schema shaped like parse(value): T works.
Generate Swift
npx webview-bridge-kit-gen \
--contract ./bridge-contract.ts \
--lang swift \
--out ./ios/BridgeTypes.swiftOmit --out to write to standard output. The result contains message-name enums, Codable structs, a handler protocol, and runtime binding code.
enum BridgeRequestName: String, Codable {
case KAKAO_LOGIN
}
struct KakaoLoginResponse: Codable {
let accessToken: String
let expiresIn: Double?
}Generate Kotlin
npx webview-bridge-kit-gen \
--contract ./bridge-contract.ts \
--lang kotlin \
--package com.example.bridge \
--out ./android/BridgeTypes.ktThe default --package is generated. Generated data types and handler bindings use the Android runtime's kotlinx.serialization setup.
enum class BridgeRequestName {
KAKAO_LOGIN
}
@Serializable
data class KakaoLoginResponse(
val accessToken: String,
val expiresIn: Double? = null
)Options
| Option | Required | Description |
|---|---|---|
--contract <file.ts> | yes | TypeScript file containing the contract |
--lang <swift|kotlin> | yes | Output language |
--out <file> | no | Output file; omit to use standard output |
--export <name> | no | Contract export name; defaults to contract |
--package <name> | no | Kotlin package; defaults to generated |
Use --export if the contract has a different export name.
npx webview-bridge-kit-gen --contract ./bridge-contract.ts --export appBridge --lang swiftType mapping and limits
| TypeScript | Swift | Kotlin |
|---|---|---|
string | String | String |
number | Double | Double |
boolean | Bool | Boolean |
T[] | [T] | List<T> |
| object | separate Codable struct | separate @Serializable data class |
| optional field | T? | T? = null |
JSON has only one numeric type, so TypeScript number always becomes Double. The generator stops with an error for types it cannot map safely, including unions, Date, bigint, and tuples, instead of emitting misleading code.
Nullable/optional object fields become nullable native properties. Nullable array elements and message or field identifiers that are unsafe in Swift/Kotlin fail with an explicit error.
Treat the output as generated code
Add the command to a build script or CI so the stubs are regenerated whenever the contract changes. Generated files include a do-not-edit header.