native
Every export of @kitr/native, @kitr/native/react, @kitr/native/provider, @kitr/native/driver, @kitr/native/drivers/web, @kitr/native/drivers/electron, @kitr/native/drivers/tauri, @kitr/native/drivers/capacitor, read from the published type definitions. The guide shows them in use.
@kitr/native
capacitorClipboard
function capacitorClipboard(): ClipboardDriver;
Clipboard on @capacitor/clipboard: the OS pasteboard, with no permission prompt.
capacitorGeolocation
function capacitorGeolocation(): GeolocationDriver;
Location on @capacitor/geolocation (Core Location, Fused Location). Asks for the location
permission first, as Android needs; rejects when it is refused.
capacitorHaptics
function capacitorHaptics(): HapticsDriver;
Haptics on @capacitor/haptics: the Taptic Engine on iOS, the vibrator on Android.
capacitorShare
function capacitorShare(): ShareDriver;
Share sheet on @capacitor/share. Resolves false when dismissed. File objects cannot cross the
bridge, so a payload with files is not shareable here: save the file with @kitr/files and share its url.
createCapacitorNativeDrivers
function createCapacitorNativeDrivers(_options?: DriverOptions): Driver;
The native drivers for the Capacitor shell: clipboard, share sheet, haptics and geolocation on the
official plugins, each imported on first use. Camera and biometrics have no Capacitor driver yet
(supported: false); register one with app.drivers.register().
createElectronNativeDriver
function createElectronNativeDriver(_options?: DriverOptions): ElectronNativeDriver;
The native driver for the Electron shell, served over the kitr:native:* and kitr:shell:open
channels of handleKitrIpc(). Capabilities: clipboard (Electron's clipboard) and biometrics
(Touch ID on macOS; available() is false elsewhere). share, haptics, geolocation and
camera are null: a desktop has no share sheet or haptic motor, and the Chromium
geolocation needs a Google key, so those report supported: false rather than pretend.
driver.system has what desktop apps want beyond them: openExternal, appVersion,
platform, the system theme, online status and powerMonitor events.
Throws E_DRIVER_UNAVAILABLE when the preload bridge is missing (no exposeIpc() call).
createMemoryNativeDrivers
function createMemoryNativeDrivers(overrides?: NativeConfig['drivers']): {
clipboard: ClipboardDriver;
share: ShareDriver;
haptics: HapticsDriver;
geolocation: GeolocationDriver;
camera: CameraDriver;
biometrics: BiometricsDriver;
shared: SharePayload[];
haptics_log: HapticKind[];
};
In-memory drivers for all six capabilities, for tests and the server. shared and haptics_log
record what was shared and played; pass overrides to replace any driver.
createNative
function createNative(config?: NativeConfig, app?: KitrApp): Native;
Build the native service. Per capability it uses config.drivers, else the driver a platform
registered on app, else the one selectDriver() picks for the runtime (the web drivers in a
browser; in a native shell E_DRIVER_UNAVAILABLE unless fallbackToWeb is set), else an
unsupported stand-in.
createTauriNativeDriver
function createTauriNativeDriver(_options?: DriverOptions): TauriNativeDriver;
The native driver for the Tauri shell. clipboard is @tauri-apps/plugin-clipboard-manager;
share, haptics, geolocation, camera and biometrics are null (the matching Tauri
plugins are mobile-only, and a Tauri mobile build runs under Capacitor's driver set instead of
this one). driver.system has openExternal (@tauri-apps/plugin-opener), platform
(@tauri-apps/plugin-os), appVersion and the system theme (@tauri-apps/api) and online
status. Each plugin is imported on first use and is an optional peer: a missing one makes the
call that needs it reject with E_DRIVER_UNAVAILABLE.
selectDriver
function selectDriver(runtime: Runtime, options?: DriverOptions): Driver;
The capability drivers for a runtime: the browser APIs on web, and each native shell's own
(Capacitor plugins, Electron dialogs, Tauri plugins). A shell with no drivers yet throws
E_DRIVER_UNAVAILABLE rather than falling back to the web ones, unless fallbackToWeb is set.
useNative
function useNative(app: KitrApp): Native;
The app's native service, outside React. Same as app.container.use('native').
webBiometrics
function webBiometrics(options?: {
storageKey?: string;
}): BiometricsDriver | null;
WebAuthn user verification with a platform authenticator (Touch ID, Windows Hello, Android screen lock). The first call registers a device-only credential for this site (that prompt is itself the check); later calls ask for that credential by id, so people without a passkey get the fingerprint or PIN prompt rather than an empty passkey picker. A local presence check, like the native ones: to prove identity to your server, verify a WebAuthn assertion there.
webCamera
function webCamera(): CameraDriver | null;
Camera driver that opens a hidden image file input, with capture for the camera source.
Resolves null when cancelled; null itself only where there is no document.
webClipboard
function webClipboard(): ClipboardDriver | null;
Clipboard driver on the Clipboard API. Null where navigator.clipboard is missing (no HTTPS, no browser).
webGeolocation
function webGeolocation(): GeolocationDriver | null;
Geolocation driver on the browser Geolocation API. Null where navigator.geolocation is missing.
webHaptics
function webHaptics(): HapticsDriver | null;
Haptics driver that maps each kind to a navigator.vibrate pattern. Null where vibration is missing.
webShare
function webShare(): ShareDriver | null;
Share driver on Web Share. Resolves false when dismissed; null where navigator.share is missing.
UnsupportedError
class UnsupportedError extends Error {
capability: NativeCapability;
constructor(capability: NativeCapability);
}
Thrown when a method is called on a capability that has no driver here. capability names it.
defineConfig
const defineConfig: <const C extends NativeConfig>(config: C) => C;
Types config/native.ts. Returns the object unchanged.
BiometricsDriver
interface BiometricsDriver {
/** Whether the device has an enrolled biometric or device credential. */
available(): Promise<boolean>;
/** Prompt; resolves to true on success, false when cancelled or failed. */
authenticate(options?: {
reason?: string;
}): Promise<boolean>;
}
Asks for a fingerprint, face or device PIN to confirm someone is at the device.
CameraDriver
interface CameraDriver {
/** Take a photo (or, on the web, open the capture-enabled file input). */
capture(options?: {
source?: 'camera' | 'library';
quality?: number;
}): Promise<Photo | null>;
}
Takes or picks a photo.
Capability
interface Capability<T> {
/** True when a driver exists for this capability here. */
supported: boolean;
/** The active driver (a stand-in that rejects with `UnsupportedError` when unsupported). */
driver: T;
/** Where the driver came from: `configured`, the registering platform, `native`, `web` or `unsupported`. */
name: string;
}
What every capability on the native service carries next to its driver's methods.
ClipboardDriver
/** Reads and writes plain text on the system clipboard. */
interface ClipboardDriver {
/** Resolves to the clipboard's text. Browsers ask permission first and reject when refused. */
readText(): Promise<string>;
/** Puts `text` on the clipboard. On the web, call it from a click or key press. */
writeText(text: string): Promise<void>;
}
Reads and writes plain text on the system clipboard.
DesktopSystem
interface DesktopSystem {
/** The operating system: `darwin`, `win32`, `linux` (Electron) or `macos`, `windows`, `linux` (Tauri). */
platform(): Promise<string>;
/** The app's version from `package.json` / `tauri.conf.json`. */
appVersion(): Promise<string>;
/** Open a link in the default browser. Only `http:`, `https:`, `mailto:` and `tel:` are allowed. */
openExternal(url: string): Promise<void>;
/** Whether the system is in dark mode. */
isDark(): Promise<boolean>;
/** Listen for the system switching between light and dark. Returns the unsubscribe function. */
onTheme(listener: (dark: boolean) => void): () => void;
/** Whether the machine has a network connection. */
isOnline(): Promise<boolean>;
}
What a desktop shell knows that the six capabilities do not cover.
Driver
interface Driver {
/** Where the drivers come from, shown as the capability's `name`: `web`, `electron`, `tauri`, `capacitor`. */
name: string;
clipboard: ClipboardDriver | null;
share: ShareDriver | null;
haptics: HapticsDriver | null;
geolocation: GeolocationDriver | null;
camera: CameraDriver | null;
biometrics: BiometricsDriver | null;
}
What one runtime supplies for the native service: a driver per capability, or null where
the runtime has none (the capability then reports supported: false).
ElectronNativeDriver
interface ElectronNativeDriver extends Driver {
/** Desktop-only helpers; also `onPower` and `isOnBattery`, which only Electron has. */
system: DesktopSystem & {
/** Suspend, resume and battery/AC changes from Electron's `powerMonitor`. */
onPower(listener: (event: PowerEvent) => void): () => void;
/** Whether the computer runs on battery now. */
isOnBattery(): Promise<boolean>;
};
}
The Electron driver: the capabilities Electron has plus the system helpers.
GeolocationDriver
interface GeolocationDriver {
/** Resolve the current position. `highAccuracy` asks for GPS; `timeout` is in milliseconds. */
current(options?: {
highAccuracy?: boolean;
timeout?: number;
}): Promise<Position>;
/** Call `listener` with each new position until the returned function is called. */
watch(listener: (position: Position) => void, options?: {
highAccuracy?: boolean;
}): () => void;
}
Reads the device's location once or continuously.
HapticsDriver
interface HapticsDriver {
/** Play the feedback for `kind`. */
impact(kind: HapticKind): Promise<void>;
}
Plays haptic feedback (a vibration pattern on the web).
Native
interface Native {
/** Read and write the clipboard. */
clipboard: Capability<ClipboardDriver> & ClipboardDriver;
/** Open the share sheet. */
share: Capability<ShareDriver> & ShareDriver;
/** Play haptic feedback. */
haptics: Capability<HapticsDriver> & HapticsDriver;
/** Read or follow the device's location. */
geolocation: Capability<GeolocationDriver> & GeolocationDriver;
/** Take or pick a photo. */
camera: Capability<CameraDriver> & CameraDriver;
/** Confirm presence with a fingerprint, face or device PIN. */
biometrics: Capability<BiometricsDriver> & BiometricsDriver;
/** Which capabilities have a working driver, for devtools and feature gating. */
supported(): Record<NativeCapability, boolean>;
}
The native service: six device capabilities, each with its methods and its supported flag.
NativeConfig
interface NativeConfig {
/** Replace individual drivers (tests, custom hardware). */
drivers?: Partial<{
clipboard: ClipboardDriver;
share: ShareDriver;
haptics: HapticsDriver;
geolocation: GeolocationDriver;
camera: CameraDriver;
biometrics: BiometricsDriver;
}>;
/**
* In a native shell (Electron, Tauri, Capacitor) with no native drivers, use the web drivers
* inside the WebView instead of throwing `E_DRIVER_UNAVAILABLE`. Default false.
*/
fallbackToWeb?: boolean;
}
Options for config/native.ts and createNative().
Photo
interface Photo {
/** The image data (a `File` on the web). */
blob: Blob;
/** Its MIME type, such as `image/jpeg`. */
type: string;
/** Where the image came from. */
source: 'camera' | 'library';
}
A photo taken with the camera or picked from the library.
Position
interface Position {
/** Degrees north of the equator. */
latitude: number;
/** Degrees east of Greenwich. */
longitude: number;
/** Radius of uncertainty, in metres. */
accuracy: number;
/** Metres above sea level, or null when unknown. */
altitude?: number | null;
/** Direction of travel in degrees from north, or null when unknown. */
heading?: number | null;
/** Metres per second, or null when unknown. */
speed?: number | null;
/** When the fix was taken, in milliseconds since the epoch. */
timestamp: number;
}
A location fix, in the shape of the browser's GeolocationCoordinates plus its time.
ShareDriver
interface ShareDriver {
/** Whether this payload can be shared here, so a share button can hide itself. */
canShare(payload: SharePayload): boolean;
/** Resolves to true when shared, false when dismissed. */
share(payload: SharePayload): Promise<boolean>;
}
Opens the system share sheet.
SharePayload
interface SharePayload {
/** Title shown by targets that have one, such as an email subject. */
title?: string;
/** Body text. */
text?: string;
/** A link to share. */
url?: string;
/** Files to share. Check `canShare({ files })` first: not every device shares files. */
files?: File[];
}
What to hand to the share sheet. Every field is optional; most targets use url or text.
TauriNativeDriver
interface TauriNativeDriver extends Driver {
/** Desktop-only helpers, the same as on Electron except for power events, which Tauri has no plugin for. */
system: DesktopSystem;
}
The Tauri driver: the capabilities the plugins cover plus the system helpers.
DriverOptions
type DriverOptions = SelectDriverOptions;
Options of selectDriver().
HapticKind
type HapticKind = 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' | 'selection';
The feel of a haptic: three impact strengths, three outcomes and a selection tick.
NativeCapability
type NativeCapability = 'clipboard' | 'share' | 'haptics' | 'geolocation' | 'camera' | 'biometrics';
The name of one of the six capabilities, as used in supported() and app.drivers.register().
PowerEvent
type PowerEvent = 'suspend' | 'resume' | 'battery' | 'ac';
A change in how the computer is powered, as system.onPower reports it.
@kitr/native/react
useClipboard
function useClipboard(timeout?: number): {
copy: (text: string) => Promise<void>;
copied: boolean;
supported: boolean;
};
const { copy, copied } = useClipboard(): copy text and show a confirmation for timeout ms.
useGeolocation
function useGeolocation(options?: {
watch?: boolean;
highAccuracy?: boolean;
}): {
position: Position | null;
error: Error | null;
supported: boolean;
};
{ position, error, supported }: the current position, read on mount and updated while mounted
when watch is true. error holds a failure of the first read.
useNative
function useNative(): Native;
The app's native service in a component.
useShare
function useShare(): {
supported: boolean;
canShare: (payload: SharePayload) => boolean;
share: (payload: SharePayload) => Promise<boolean>;
};
const { share, canShare } = useShare(): the share sheet, with a flag to hide the button where there is none.
@kitr/native/provider
nativeProvider
const nativeProvider: import("@kitr/core").KitrProvider;
Binds native from the drivers platform packages registered (clipboard, share, haptics,
geolocation, camera, biometrics) with web drivers for the rest.
@kitr/native/driver
selectDriver
function selectDriver(runtime: Runtime, options?: DriverOptions): Driver;
The capability drivers for a runtime: the browser APIs on web, and each native shell's own
(Capacitor plugins, Electron dialogs, Tauri plugins). A shell with no drivers yet throws
E_DRIVER_UNAVAILABLE rather than falling back to the web ones, unless fallbackToWeb is set.
Driver
interface Driver {
/** Where the drivers come from, shown as the capability's `name`: `web`, `electron`, `tauri`, `capacitor`. */
name: string;
clipboard: ClipboardDriver | null;
share: ShareDriver | null;
haptics: HapticsDriver | null;
geolocation: GeolocationDriver | null;
camera: CameraDriver | null;
biometrics: BiometricsDriver | null;
}
What one runtime supplies for the native service: a driver per capability, or null where
the runtime has none (the capability then reports supported: false).
DriverOptions
type DriverOptions = SelectDriverOptions;
Options of selectDriver().
@kitr/native/drivers/web
webBiometrics
function webBiometrics(options?: {
storageKey?: string;
}): BiometricsDriver | null;
WebAuthn user verification with a platform authenticator (Touch ID, Windows Hello, Android screen lock). The first call registers a device-only credential for this site (that prompt is itself the check); later calls ask for that credential by id, so people without a passkey get the fingerprint or PIN prompt rather than an empty passkey picker. A local presence check, like the native ones: to prove identity to your server, verify a WebAuthn assertion there.
webCamera
function webCamera(): CameraDriver | null;
Camera driver that opens a hidden image file input, with capture for the camera source.
Resolves null when cancelled; null itself only where there is no document.
webClipboard
function webClipboard(): ClipboardDriver | null;
Clipboard driver on the Clipboard API. Null where navigator.clipboard is missing (no HTTPS, no browser).
webGeolocation
function webGeolocation(): GeolocationDriver | null;
Geolocation driver on the browser Geolocation API. Null where navigator.geolocation is missing.
webHaptics
function webHaptics(): HapticsDriver | null;
Haptics driver that maps each kind to a navigator.vibrate pattern. Null where vibration is missing.
webShare
function webShare(): ShareDriver | null;
Share driver on Web Share. Resolves false when dismissed; null where navigator.share is missing.
@kitr/native/drivers/electron
createElectronDriver
function createElectronDriver(_options?: DriverOptions): ElectronNativeDriver;
The native driver for the Electron shell, served over the kitr:native:* and kitr:shell:open
channels of handleKitrIpc(). Capabilities: clipboard (Electron's clipboard) and biometrics
(Touch ID on macOS; available() is false elsewhere). share, haptics, geolocation and
camera are null: a desktop has no share sheet or haptic motor, and the Chromium
geolocation needs a Google key, so those report supported: false rather than pretend.
driver.system has what desktop apps want beyond them: openExternal, appVersion,
platform, the system theme, online status and powerMonitor events.
Throws E_DRIVER_UNAVAILABLE when the preload bridge is missing (no exposeIpc() call).
DesktopSystem
interface DesktopSystem {
/** The operating system: `darwin`, `win32`, `linux` (Electron) or `macos`, `windows`, `linux` (Tauri). */
platform(): Promise<string>;
/** The app's version from `package.json` / `tauri.conf.json`. */
appVersion(): Promise<string>;
/** Open a link in the default browser. Only `http:`, `https:`, `mailto:` and `tel:` are allowed. */
openExternal(url: string): Promise<void>;
/** Whether the system is in dark mode. */
isDark(): Promise<boolean>;
/** Listen for the system switching between light and dark. Returns the unsubscribe function. */
onTheme(listener: (dark: boolean) => void): () => void;
/** Whether the machine has a network connection. */
isOnline(): Promise<boolean>;
}
What a desktop shell knows that the six capabilities do not cover.
ElectronNativeDriver
interface ElectronNativeDriver extends Driver {
/** Desktop-only helpers; also `onPower` and `isOnBattery`, which only Electron has. */
system: DesktopSystem & {
/** Suspend, resume and battery/AC changes from Electron's `powerMonitor`. */
onPower(listener: (event: PowerEvent) => void): () => void;
/** Whether the computer runs on battery now. */
isOnBattery(): Promise<boolean>;
};
}
The Electron driver: the capabilities Electron has plus the system helpers.
PowerEvent
type PowerEvent = 'suspend' | 'resume' | 'battery' | 'ac';
A change in how the computer is powered, as system.onPower reports it.
@kitr/native/drivers/tauri
createTauriDriver
function createTauriDriver(_options?: DriverOptions): TauriNativeDriver;
The native driver for the Tauri shell. clipboard is @tauri-apps/plugin-clipboard-manager;
share, haptics, geolocation, camera and biometrics are null (the matching Tauri
plugins are mobile-only, and a Tauri mobile build runs under Capacitor's driver set instead of
this one). driver.system has openExternal (@tauri-apps/plugin-opener), platform
(@tauri-apps/plugin-os), appVersion and the system theme (@tauri-apps/api) and online
status. Each plugin is imported on first use and is an optional peer: a missing one makes the
call that needs it reject with E_DRIVER_UNAVAILABLE.
TauriNativeDriver
interface TauriNativeDriver extends Driver {
/** Desktop-only helpers, the same as on Electron except for power events, which Tauri has no plugin for. */
system: DesktopSystem;
}
The Tauri driver: the capabilities the plugins cover plus the system helpers.
@kitr/native/drivers/capacitor
capacitorClipboard
function capacitorClipboard(): ClipboardDriver;
Clipboard on @capacitor/clipboard: the OS pasteboard, with no permission prompt.
capacitorGeolocation
function capacitorGeolocation(): GeolocationDriver;
Location on @capacitor/geolocation (Core Location, Fused Location). Asks for the location
permission first, as Android needs; rejects when it is refused.
capacitorHaptics
function capacitorHaptics(): HapticsDriver;
Haptics on @capacitor/haptics: the Taptic Engine on iOS, the vibrator on Android.
capacitorShare
function capacitorShare(): ShareDriver;
Share sheet on @capacitor/share. Resolves false when dismissed. File objects cannot cross the
bridge, so a payload with files is not shareable here: save the file with @kitr/files and share its url.
createCapacitorDriver
function createCapacitorDriver(_options?: DriverOptions): Driver;
The native drivers for the Capacitor shell: clipboard, share sheet, haptics and geolocation on the
official plugins, each imported on first use. Camera and biometrics have no Capacitor driver yet
(supported: false); register one with app.drivers.register().