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",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{ "name": "/absolute/path/to/sidecar", "sidecar": true },
{ "name": "relative/path/to/binary", "sidecar": true },
{ "name": "binaries/my-sidecar", "sidecar": true }
]
}
}
}
}
A binary with the same name and a -$TARGET_TRIPLE
suffix must exist on the specified path. For instance, "externalBin": ["binaries/my-sidecar"]
requires a src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu
executable on Linux. You can find the current platform's target triple by looking at the host:
property reported by the rustc -Vv
command.
If the grep
and cut
commands are available, as they should on most Unix systems, you can extract the target triple directly with the following command:
rustc -Vv | grep host | cut -f2 -d' '
On Windows you can use PowerShell instead:
rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}
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 it from JavaScript​
In 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 shell > scope
.
import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
const command = Command.sidecar('binaries/my-sidecar')
const output = await command.execute()
Running it from Rust​
On the Rust side, import the Command
struct from the tauri::api::process
module:
// `new_sidecar()` expects just the filename, NOT the whole path like in JavaScript
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 (Tauri's CLI will do this for you once you changed the config):
# Cargo.toml
[dependencies]
tauri = { version = "1", features = ["process-command-api", ...] }
Passing arguments​
You can pass arguments to Sidecar commands just like you would for running normal Command
s (see Restricting access to the Command APIs).
First, define the arguments that need to be passed to the Sidecar command in tauri.conf.json
:
{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{
"name": "binaries/my-sidecar",
"sidecar": true,
"args": [
"arg1",
"-a",
"--arg2",
{
"validator": "\\S+"
}
]
}
]
}
}
}
}
Then, to call the sidecar command, simply pass in all the arguments as an array:
import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
// notice that the args array matches EXACTLY what is specified on `tauri.conf.json`.
const command = Command.sidecar('binaries/my-sidecar', [
'arg1',
'-a',
'--arg2',
'any-string-that-matches-the-validator',
])
const output = await command.execute()
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.