Crates.io | esbuild_client |
lib.rs | esbuild_client |
version | 0.7.1 |
created_at | 2025-06-04 22:17:48.828523+00 |
updated_at | 2025-09-05 23:16:22.32236+00 |
description | A Rust implementation of a client for communicating with esbuild's service API over stdio |
homepage | |
repository | https://github.com/denoland/esbuild_client |
max_upload_size | |
id | 1700923 |
size | 151,648 |
A Rust implementation of a client for communicating with esbuild's service API over stdio. This project implements the binary protocol used by esbuild to encode and decode messages between the client and the service.
Create an EsbuildService
, and send a build request:
use esbuild_client::{EsbuildFlagsBuilder, EsbuildService, protocol::BuildRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// using a no-op plugin handler
let esbuild = esbuild_client::EsbuildService::new("/path/to/esbuild/binary", "0.25.5", None);
let flags = esbuild_client::EsbuildFlagsBuilder::default()
.bundle(true)
.minify(true)
.format(esbuild::Format::Esm)
.build_with_defaults();
let response = esbuild
.client()
.send_build_request(esbuild_client::protocol::BuildRequest {
entries: vec![("output.js".into(), "input.js".into())],
flags,
..Default::default()
})
.await?;
println!("build response: {:?}", response);
Ok(())
}
Custom plugin handling:
use esbuild_client::{EsbuildFlagsBuilder, EsbuildService, PluginHandler, protocol::BuildRequest};
struct MyPluginHandler;
#[async_trait::async_trait(?Send)]
impl PluginHandler for MyPluginHandler {
async fn on_resolve(&self, args: OnResolveArgs) -> Result<Option<OnResolveResult>, AnyError> {
println!("on_resolve: {:?}", args);
Ok(None)
}
async fn on_load(&self, args: OnLoadArgs) -> Result<Option<OnLoadResult>, AnyError> {
println!("on_load: {:?}", args);
Ok(None)
}
async fn on_start(&self, args: OnStartArgs) -> Result<Option<OnStartResult>, AnyError> {
println!("on_start: {:?}", args);
Ok(None)
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let esbuild = esbuild_client::EsbuildService::new(
"/path/to/esbuild/binary",
"0.25.5",
Arc::new(MyPluginHandler),
);
let flags = esbuild_client::EsbuildFlagsBuilder::default()
.bundle(true)
.minify(true)
.format(esbuild::Format::Esm)
.build_with_defaults();
let response = esbuild
.client()
.send_build_request(esbuild_client::protocol::BuildRequest {
entries: vec![("output.js".into(), "input.js".into())],
flags,
plugins: Some(vec![esbuild_client::protocol::BuildPlugin {
name: "my-plugin".into(),
on_resolve: vec![esbuild_client::protocol::OnResolveSetupOptions {
id: 0,
filter: ".*".into(),
namespace: "my-plugin".into(),
}],
on_load: vec![esbuild_client::protocol::OnLoadSetupOptions {
id: 0,
filter: ".*".into(),
namespace: "my-plugin".into(),
}],
on_start: true,
on_end: false,
}]),
..Default::default()
})
.await?;
println!("build response: {:?}", response);
Ok(())
}
src/protocol.rs
)Defines the data structures and types that correspond to esbuild API messages:
BuildRequest
,
ServeRequest
, etc.)src/protocol/encode.rs
)Implements the custom binary protocol encoding, based off of the implementation
in npm:esbuild
.
src/lib.rs
)Manages the connection to the esbuild service: