본문으로 건너뛰기

Embedding External Binaries

You may need to embed depending binaries to make your application work or prevent users from installing additional dependencies (e.g., Node.js or Python). We call this binary a sidecar.

To bundle the binaries of your choice, you can add the externalBin property to the tauri > bundle object in your tauri.conf.json.

See more about tauri.conf.json configuration here.

externalBin expects a list of strings targeting binaries either with absolute or relative paths.

Here is a sample to illustrate the configuration. This is not a complete tauri.conf.json file:

{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"bin/python"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{ "name": "/absolute/path/to/sidecar", "sidecar": true },
{ "name": "relative/path/to/binary", "sidecar": true },
{ "name": "bin/python", "sidecar": true }
]
}
}
}
}

A binary with the same name and a -$TARGET_TRIPLE suffix must exist on the specified path. For instance, "externalBin": ["bin/python"] requires a src-tauri/bin/python-x86_64-unknown-linux-gnu executable on Linux. You can find the current platform's target triple running the following command:

rustc -Vv | grep host | cut -f2 -d' '

Here's a Node.js script to append the target triple to a binary:

const execa = require('execa')
const fs = require('fs')

let extension = ''
if (process.platform === 'win32') {
extension = '.exe'
}

async function main() {
const rustInfo = (await execa('rustc', ['-vV'])).stdout
const targetTriple = /host: (\S+)/g.exec(rustInfo)[1]
if (!targetTriple) {
console.error('Failed to determine platform target triple')
}
fs.renameSync(
`src-tauri/binaries/sidecar${extension}`,
`src-tauri/binaries/sidecar-${targetTriple}${extension}`
)
}

main().catch((e) => {
throw e
})

Running on JavaScript

On the JavaScript code, import the Command class on the shell module and use the sidecar static method.

Note that you must configure the allowlist to enable shell > sidecar and configure all binaries in the shell scope.

import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `my-sidecar` is the value specified on `tauri.conf.json > tauri > bundle > externalBin`
const command = Command.sidecar('my-sidecar')
const output = await command.execute()

Running on Rust

On the Rust code, import the Command struct from the tauri::api::process module:

let (mut rx, mut child) = Command::new_sidecar("my-sidecar")
.expect("failed to create `my-sidecar` binary command")
.spawn()
.expect("Failed to spawn sidecar");

tauri::async_runtime::spawn(async move {
// read events such as stdout
while let Some(event) = rx.recv().await {
if let CommandEvent::Stdout(line) = event {
window
.emit("message", Some(format!("'{}'", line)))
.expect("failed to emit event");
// write to stdin
child.write("message from Rust\n".as_bytes()).unwrap();
}
}
});

Note that you must enable the process-command-api Cargo feature:

# Cargo.toml
[dependencies]
tauri = { version = "1", features = ["process-command-api", ...] }

Using Node.js on a Sidecar

The Tauri sidecar example demonstrates how to use the sidecar API to run a Node.js application on Tauri. It compiles the Node.js code using pkg and uses the scripts above to run it.