EIPC
Documentation

Interfaces Overview

Define your IPC API surface with interfaces.

Interfaces define the actual APIs exposed between your main and renderer processes. They are the core building block of EIPC.

Basic Interface

[RendererAPI]
[ContextBridge]
interface Settings {
  getTheme() -> string
  setTheme(theme: string)
  getLocale() -> string
}

Interface Attributes

Interfaces can have attributes that modify their behavior:

AttributeDescription
[RendererAPI]API is called from renderer, implemented in main
[ContextBridge]Automatically expose via contextBridge.exposeInMainWorld
[Validator=Name]Apply a security validator to all methods

RendererAPI

The [RendererAPI] attribute indicates that the interface is called from the renderer process and implemented in the main process. This is the most common pattern.

[RendererAPI]
interface MyAPI {
  doSomething() -> string
}

ContextBridge

The [ContextBridge] attribute automatically exposes the API via Electron’s contextBridge.exposeInMainWorld, making it available to import in your renderer:

module MyApp

[RendererAPI]
[ContextBridge]
interface Settings {
  getTheme() -> string
}

Import and use in your renderer:

import { Settings } from '../ipc/renderer/MyApp';

const theme = await Settings.getTheme();

Validator

Apply a security validator to protect all methods in the interface:

validator OnlyMyApp = AND(
  origin is "https://myapp.com"
  is_main_frame is true
)

[RendererAPI]
[Validator=OnlyMyApp]
[ContextBridge]
interface SecureAPI {
  getSensitiveData() -> string
}

Methods

Methods define the operations available on an interface:

interface MyAPI {
  // Simple method with no arguments
  ping() -> string

  // Method with arguments
  greet(name: string) -> string

  // Method with multiple arguments
  calculate(a: number, b: number) -> number

  // Method with optional return
  findUser(id: number) -> User?

  // Method with no return value
  logMessage(message: string)
}

Return Types

  • -> Type — Returns a value of the specified type
  • -> Type? — Returns an optional value (can be null/undefined)
  • No arrow — Method returns nothing (void)

Main Process Implementation

In your main process, implement the interface:

import { Settings } from '../ipc/browser/MyApp';
import { nativeTheme, app } from 'electron';

Settings.for(mainWindow.webContents).setImplementation({
  async getTheme() {
    return nativeTheme.themeSource;
  },

  async setTheme(theme) {
    nativeTheme.themeSource = theme;
  },

  async getLocale() {
    return app.getLocale();
  },
});

Frame-Specific Implementations

You can set different implementations for different frames:

// Main frame - full access
Settings.for(mainWindow.webContents.mainFrame).setImplementation({
  async getTheme() {
    return nativeTheme.themeSource;
  },
  async setTheme(theme) {
    nativeTheme.themeSource = theme;
  },
  // ...
});

// Iframe - read-only access
Settings.for(iframeWebContents.mainFrame).setImplementation({
  async getTheme() {
    return nativeTheme.themeSource;
  },
  async setTheme(theme) {
    throw new Error('Not allowed in iframe');
  },
  // ...
});

Preload Setup

Import the generated preload code to expose the API:

// preload.ts
import './ipc/preload/MyApp';

This must be bundled before use. See Installation for bundling instructions.

Renderer Usage

Call the API from your renderer process:

import { Settings } from '../ipc/renderer/MyApp';

// Fully typed!
const theme = await Settings.getTheme();
const locale = await Settings.getLocale();

await Settings.setTheme('dark');

Multiple Interfaces

You can define multiple interfaces in a single schema file:

module MyApp

[RendererAPI]
[ContextBridge]
interface Settings {
  getTheme() -> string
  setTheme(theme: string)
}

[RendererAPI]
[ContextBridge]
interface App {
  getVersion() -> string
  getLocale() -> string
  quit()
}

Each interface can be imported separately:

import { Settings, App } from '../ipc/renderer/MyApp';

await Settings.getTheme();
await App.getVersion();

Next Steps

  • Methods — Learn about sync and async methods
  • Events — Send events from main to renderer
  • Stores — Reactive state with React hooks