nativeMessaging Permission

5 min read

nativeMessaging Permission

Overview

Manifest Declaration

{ "permissions": ["nativeMessaging"] }

User warning: “Communicate with cooperating native applications”

API Methods

Persistent Connection

chrome.runtime.connectNative(hostName) returns Port for persistent connection.

Port Methods: Port.postMessage(msg), Port.onMessage, Port.onDisconnect

const port = chrome.runtime.connectNative('com.example.myhost');
port.onMessage.addListener((msg) => console.log('From native:', msg));
port.onDisconnect.addListener(() => {
  if (chrome.runtime.lastError) console.error('Disconnect:', chrome.runtime.lastError.message);
});
port.postMessage({ action: 'startMonitoring' });

One-Shot Messages

chrome.runtime.sendNativeMessage(hostName, message) — single request/response.

const response = await chrome.runtime.sendNativeMessage('com.example.myhost', {
  action: 'getVersion'
});
console.log(response.version);

Native Messaging Host Setup

Host Manifest (JSON)

{
  "name": "com.example.myhost",
  "description": "My native messaging host",
  "path": "/path/to/native/app",
  "type": "stdio",
  "allowed_origins": ["chrome-extension://abcdef.../"]
}

Registration by OS

| OS | Path | |—|—| | macOS | ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.example.myhost.json | | Linux | ~/.config/google-chrome/NativeMessagingHosts/com.example.myhost.json | | Windows | Registry: HKCU\Software\Google\Chrome\NativeMessagingHosts\com.example.myhost |

Message Format

Native Host Example (Python)

import struct, sys, json

def read_message():
    raw_length = sys.stdin.buffer.read(4)
    if not raw_length: return None
    length = struct.unpack('=I', raw_length)[0]
    return json.loads(sys.stdin.buffer.read(length))

def send_message(msg):
    encoded = json.dumps(msg).encode('utf-8')
    sys.stdout.buffer.write(struct.pack('=I', len(encoded)))
    sys.stdout.buffer.write(encoded)
    sys.stdout.buffer.flush()

while (msg := read_message()):
    if msg.get('action') == 'getVersion':
        send_message({'version': '1.0.0'})

Use Cases

Security Considerations

Code Examples

One-Shot Message Pattern

async function sendNativeMessage(hostName: string, message: object) {
  try {
    return await chrome.runtime.sendNativeMessage(hostName, message);
  } catch (error) {
    console.error('Native message failed:', error);
    throw error;
  }
}
const version = await sendNativeMessage('com.example.myhost', { action: 'getVersion' });

Persistent Connection with Reconnect

class NativeHostConnection {
  private port: chrome.runtime.Port | null = null;
  private attempts = 0;
  constructor(private hostName: string) {}

  connect(): void {
    this.port = chrome.runtime.connectNative(this.hostName);
    this.port.onMessage.addListener((msg) => console.log('Received:', msg));
    this.port.onDisconnect.addListener(() => {
      this.port = null;
      if (this.attempts++ < 3) setTimeout(() => this.connect(), 1000 * this.attempts);
    });
  }

  send(message: object): void { this.port?.postMessage(message); }
}

Error Handling

chrome.runtime.connectNative('com.example.myhost', (port) => {
  if (chrome.runtime.lastError) {
    const err = chrome.runtime.lastError.message;
    if (err.includes('not found')) console.error('Host not installed');
    else if (err.includes('exited')) console.error('Host crashed');
    else if (err.includes('forbidden')) console.error('Check allowed_origins');
    return;
  }
  port.onMessage.addListener(handleMessage);
});

Common Errors

Cross-References

Frequently Asked Questions

How do I communicate with a native app?

Use chrome.runtime.sendNativeMessage() to send messages to a native application configured in your manifest. The app must register a messaging host.

Is nativeMessaging secure?

NativeMessaging is secure but requires user consent and careful validation of messages to prevent injection attacks. —

Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.

No previous article
No next article