Spec files
A spec file is the single source of truth for a native module. It is a plain TypeScript file whose interfaces drive codegen for both sides of the bridge.
Rules
- Filename — any
.spec.tsfile is a valid input toyolk-codegen. - Interface name — must end with
Spec. The module name is derived by stripping the suffix:CounterSpec→ module namedCounter. - Return types — every method must return
Promise<T>. Synchronous methods are not supported across the bridge. - Supported types —
string,number,boolean,void,null, arrays, and plain objects. Generics and union types beyondT | nullare not yet supported.
Example
export interface StorageSpec {
get(key: string): Promise<string | null>
set(key: string, value: string): Promise<void>
delete(key: string): Promise<void>
}
What codegen produces
From the spec above, yolk-codegen generates:
Swift — a protocol with a dispatch table:
public protocol StorageModule: YolkModule {
func get(key: String) async throws -> String?
func set(key: String, value: String) async throws -> Void
func delete(key: String) async throws -> Void
}
TypeScript — a proxy class:
export class Storage extends NativeModule {
get(key: string): Promise<string | null> { ... }
set(key: string, value: string): Promise<void> { ... }
delete(key: string): Promise<void> { ... }
}
One spec, all platforms
The spec file lives in your shared logic/ directory. Codegen targets differ per platform:
# macOS
yolk-codegen storage.spec.ts ./macos/Generated ./logic/src/generated
# iOS (future)
yolk-codegen storage.spec.ts ./ios/Generated ./logic/src/generated
The TypeScript output is the same for all platforms. Only the Swift (or Kotlin, or C) output changes.