A persistent CSharpier formatting daemon with automatic server management and idle timeout.
  • TypeScript 100%
Find a file
2026-08-10 17:47:03 +02:00
.gitignore added --status 2025-10-23 18:01:27 +02:00
bun.lock first commit 2025-10-23 17:39:31 +02:00
CLAUDE.md first commit 2025-10-23 17:39:31 +02:00
index.ts updated csharpier support 2026-08-10 17:47:03 +02:00
package.json updated csharpier support 2026-08-10 17:47:03 +02:00
README.md updated csharpier support 2026-08-10 17:47:03 +02:00
tsconfig.json first commit 2025-10-23 17:39:31 +02:00

csharpierd

A persistent CSharpier formatting daemon with automatic server management and idle timeout.

Features

  • Starts CSharpier server in background on first use
  • Reuses existing server for subsequent formatting requests
  • Automatically shuts down after 1 hour of inactivity
  • Thread-safe with file locking mechanism
  • Auto-recovery if server crashes

Requirements

  • Bun runtime (>= 1.0.0)
  • CSharpier 1.3.0 or newer (1.x), installed globally or locally

Supported CSharpier versions

csharpierd CSharpier
>= 2.0.0 1.3.0 1.x
<= 1.0.5 1.2.x and earlier

CSharpier 1.3.0 replaced the ASP.NET Core host of csharpier server with a plain HttpListener. HttpListener matches incoming requests against its registered prefix (http://127.0.0.1:<port>/) by Host header, so requests addressed to localhost no longer match and are answered with 404 Not Found. csharpierd now talks to 127.0.0.1 directly.

csharpierd checks the installed CSharpier version before starting the server and fails with a clear message on unsupported versions rather than producing confusing 404s. If you are stuck on an older CSharpier, pin csharpierd@1.0.5.

Installation

Global Installation

# Bun
bun install -g csharpierd

# npm
npm install -g csharpierd

# Yarn
yarn global add csharpierd

# pnpm
pnpm install -g csharpierd

Local Development

bun install

Usage

Command Line Options

csharpierd <filename> < input.cs    # Format C# code from stdin
csharpierd --start                  # Start and prewarm the server
csharpierd --status                 # Show server status
csharpierd --stop                   # Stop the background server
csharpierd --help                   # Show help message

As Global Command

After global installation:

# Format a C# file
csharpierd Program.cs < Program.cs

# Or using cat
cat MyFile.cs | csharpierd MyFile.cs

# Output formatted code to a new file
csharpierd MyFile.cs < MyFile.cs > MyFile.formatted.cs

# Check server status
csharpierd --status

# Stop the background server
csharpierd --stop

# Show help
csharpierd --help

Local Development

# Format a file
bun index.ts Program.cs < Program.cs

# Check server status
bun index.ts --status

# Stop the server
bun index.ts --stop

# Show help
bun index.ts --help

Server Management

Check Server Status

The --status flag shows detailed information about the server including:

  • Running state (RUNNING, STARTING, STOPPED, or NOT RUNNING)
  • Process ID and port
  • Last access time
  • Idle time with color-coded warnings (green < 75% timeout, yellow >= 75%, red >= 100%)
  • Configuration details
csharpierd --status

Stopping the Server

The server will automatically shut down after 1 hour of inactivity, but you can manually stop it:

csharpierd --stop

Building

You can compile the TypeScript code to a standalone binary:

bun run build

This creates a csharpierd binary in the current directory that can be distributed without requiring Bun to be installed. The binary is self-contained and includes all dependencies.

# Run the compiled binary
./csharpierd Program.cs < Program.cs

Editor Integration

Neovim with conform.nvim

conform.nvim is a popular formatter plugin for Neovim. Here's how to configure it to use csharpierd:

Basic Configuration

require("conform").setup({
  formatters_by_ft = {
    cs = { "csharpierd" },
  },
  formatters = {
    csharpierd = {
      command = "csharpierd",
      args = { "$RELATIVE_FILEPATH" },
      stdin = true,
    },
  },
})

Benefits of using csharpierd with conform.nvim

  • Fast formatting: Reuses the CSharpier server process, avoiding startup overhead
  • Automatic server management: Server starts on first use and stops after 1 hour of inactivity

How It Works

  1. First Call: Starts dotnet csharpier server --server-port 18912 in the background
  2. Subsequent Calls: Reuses the existing server process
  3. Idle Timeout: Server automatically shuts down after 1 hour of inactivity
  4. State Management: Server state (PID, port, last access time) stored in /tmp/csharpierd-state.json
  5. Concurrency: Lock file prevents race conditions when multiple instances run simultaneously

dotnet csharpier is only a launcher — it spawns the actual CSharpier process, which is what binds the port. csharpierd therefore shuts a server down by killing the whole process tree, and reclaims the port from an untracked server left behind by an earlier run before starting a new one.

Server Details

  • Port: 18912 (hardcoded, bound to 127.0.0.1)
  • State File: /tmp/csharpierd-state.json
  • Lock File: /tmp/csharpierd.lock
  • Idle Timeout: 1 hour (3600000ms)

Publishing

To publish this package to npm:

bun publish

License

MIT