esbuild_client

Crates.ioesbuild_client
lib.rsesbuild_client
version0.7.1
created_at2025-06-04 22:17:48.828523+00
updated_at2025-09-05 23:16:22.32236+00
descriptionA Rust implementation of a client for communicating with esbuild's service API over stdio
homepage
repositoryhttps://github.com/denoland/esbuild_client
max_upload_size
id1700923
size151,648
David Sherret (dsherret)

documentation

README

esbuild_client

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.

Usage

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(())
}

Layout

Protocol Module (src/protocol.rs)

Defines the data structures and types that correspond to esbuild API messages:

  • Structs representing various esbuild requests and responses (BuildRequest, ServeRequest, etc.)
  • Message serialization/deserialization logic

Encoding Module (src/protocol/encode.rs)

Implements the custom binary protocol encoding, based off of the implementation in npm:esbuild.

EsbuildService (src/lib.rs)

Manages the connection to the esbuild service:

  • Spawns and manages the esbuild service process
  • Handles communication via stdin/stdout
  • Processes messages received from the service
Commit count: 42

cargo fmt