tmux.ts - v0.1.3
    Preparing search index...

    tmux.ts - v0.1.3

    tmux.ts

    TypeScript-first programmatic tmux for Node.js and Bun.

    tmux.ts demo — a script splits the window, launches a program, and types into it

    This package is an early-stage wrapper around the tmux CLI. Commands will be added as the project needs them, rather than trying to mirror all of tmux up front.

    • Run tmux commands from Node.js and Bun
    • Provide a TypeScript API for common tmux workflows
    • Support both plain TypeScript and Effect usage
    • Keep behavior close to tmux itself
    • Add API surface incrementally
    npm install tmux.ts
    

    Requires a tmux binary of version 3.4 or newer — found on PATH by default, or point at any binary with new TmuxClient({ executable: "/path/to/tmux" }). Tested against tmux 3.4 through 3.7.

    Entry points

    The package ships ESM-only with three entry points:

    • tmux.ts — standalone Promise-based API for Node-compatible runtimes. No Effect knowledge required.
    • tmux.ts/bun — standalone Promise-based API backed by Bun platform services.
    • tmux.ts/effect — Effect-native API (TmuxClient service + base layer + tagged errors) for Effect users.

    All entry points expose the same tagged error classes (TmuxExecutableNotFound, TmuxProcessError, TmuxServerNotRunning, TmuxTargetNotFound, TmuxCommandError, TmuxParseError, TmuxCommandOptionsError, TmuxClientConfigError). Importing any entry point spawns nothing; tmux only runs when a command is called.

    import { TmuxClient, TmuxServerNotRunning } from "tmux.ts";

    const tmux = new TmuxClient();

    // Resolves with decoded sessions; rejects with TmuxServerNotRunning if no server.
    const sessions = await tmux.listSessions();

    try {
    const windows = await tmux.listWindows();
    console.log(windows);
    } catch (error) {
    // Expected tmux/config failures reject with tagged errors.
    if (error instanceof TmuxServerNotRunning) {
    console.error("no tmux server running");
    }
    }
    import { NodeServices } from "@effect/platform-node";
    import { Effect, Layer } from "effect";
    import { TmuxClient } from "tmux.ts/effect";

    const program = Effect.gen(function* () {
    const tmux = yield* TmuxClient;
    return yield* tmux.listSessions();
    }).pipe(
    Effect.provide(TmuxClient.layer().pipe(Layer.provide(NodeServices.layer))),
    );

    Effect.runPromise(program).then(console.log);

    TmuxClient.layer() requires ChildProcessSpawner; provide NodeServices.layer for Node/Deno, BunServices.layer for Bun, or a fake spawner in tests. Pass { executable, socketName, socketPath } to target a custom tmux binary/socket.

    pnpm install
    pnpm test
    pnpm check

    This project uses Effect v4 as a language. The pieces are already installed; no extra setup is needed:

    • effect — core APIs (Context, Effect, Layer, Schema) and effect/unstable/process for child processes.
    • @effect/platform-node / @effect/platform-bun — platform layers that provide ChildProcessSpawner for Promise entry points and Effect users.
    • @effect/vitestit.effect test runner.
    • @effect/language-service — Effect-specific diagnostics (wired in tsconfig.json).

    Service pattern used here (see src/internal/Client.ts): a Context.Service with a dependency-requiring layer(config?) (requires ChildProcessSpawner, so tests and non-Node platforms can provide their own services). Errors stay in the typed channel as a Schema.TaggedError; nothing runs at import time.

    Validation commands:

    pnpm typecheck   # tsc --noEmit (src only)
    pnpm diagnostics # Effect language-service diagnostics
    pnpm test # vitest
    pnpm check # Biome lint + format

    46 tmux commands are wrapped, each with typed options and results — see the API docs for per-command details:

    breakPane capturePane clearHistory deleteBuffer displayMessage hasSession joinPane killPane killServer killSession killWindow lastPane lastWindow linkWindow listPanes listSessions listWindows loadBuffer movePane moveWindow newSession newWindow nextLayout nextWindow pasteBuffer pipePane previousLayout previousWindow renameSession renameWindow resizePane resizeWindow respawnPane respawnWindow rotateWindow saveBuffer selectLayout selectPane selectWindow sendKeys setBuffer showBuffer splitWindow swapPane swapWindow unlinkWindow

    More are added incrementally.

    ISC