statically typed · compiled checks · zero target dependencies

Infrastructure
as a typed language

Pitcrew is a programming language where SSH is a keyword, not a library. The compiler catches errors before your code touches a server.

deploy.pit
// SSH is a keyword, not a library
fn deploy() string {
  `git pull origin main`
}

result := ssh deploy(), host: "prod-1.example.com", user: "deploy"
print(result)
Connecting to prod-1.example.com...
 Uploading pitcrew-remote (4.2MB)
 Executing deploy()

Already up to date.

Built for the things that
keep you up at night

Every design decision serves one goal: catch infrastructure mistakes before they reach production.

ssh

SSH as a primitive

ssh is a keyword. The compiler understands execution boundaries and enforces type safety across them.

Static type checking

Catch type mismatches, missing error handlers, and boundary violations at compile time — not at 3 AM.

01

Single binary targets

Pitcrew copies its own interpreter to remote hosts. No Python, no Ruby, no dependency hell on targets.

!

Explicit error handling

Functions declare error types. Callers must catch. No silent failures, no unchecked exceptions.

Async & parallel

Wrap any expression in async to run it concurrently. Parallelize deployments across an entire fleet.

|>

Pipes & functional

Chain transformations left-to-right with |>. Use map with blocks for readable data pipelines.

Deploy to a fleet in parallel

async wraps any expression — including SSH calls — in a concurrent operation. The type checker ensures promises never cross execution boundaries.

No thread pools to configure. No callback hell. Just prefix with async and resolve when you need the result.

compile-time safe concurrent
fleet-deploy.pit
servers := ["web-1", "web-2", "web-3", "db-1"]

servers
  |> map {|host| async ssh deploy(), host: host, user: "deploy"}
  |> map {|p| resolve(p)}

print("All servers deployed")

No silent failures. Ever.

Functions declare their error type right in the signature with !. The type checker forces every caller to handle the error or propagate it. Unhandled errors are compile errors, not runtime surprises.

Backtick commands return structured results with stdout, stderr, and status — no more checking $?.

compile-time enforced type-safe errors
restart.pit
fn restart_service() bool! string {
  status := $`systemctl restart myapp`
  if (status.status != 0) {
    error status.stderr
  }
  true
}

ssh restart_service(), host: "prod-1", user: "root" catch {|err|
  print("Failed:", err)
}

Read left to right, think left to right

The pipe operator |> chains transformations in reading order. Combined with map blocks, data flows clearly from source to result.

No nested function calls. No intermediate variables. Just a clean pipeline.

type-checked
pipeline.pit
files := fs.list("/var/log")

report := files
  |> map {|f| f.name + " (" + f.size + ")"}
  |> join(", ")

print(report)

Zero dependencies on targets

Pitcrew embeds platform-specific binaries. On SSH, it uploads a small interpreter to the remote host and communicates over a binary protocol on stdin/stdout. Nothing to install. Nothing to maintain.

[ Your machine ] [ Remote host ] deploy.pit pitcrew-remote | | parse → typecheck receive AST | | serialize AST ——— SSH + gob ———> execute | | receive result <—— stdout/gob ——— return value

How Pitcrew compares

Not every tool is wrong for the job. But if you want type safety and compile-time guarantees for infrastructure code, the field is narrow.

Pitcrew Bash Ansible Python + Paramiko
Static type checking Yes No No Optional (mypy)
SSH is a language primitive Yes External cmd Module Library
Compile-time boundary checks Yes No No No
Forced error handling Yes set -e ignore_errors try/except
Target dependencies None None Python Python
Parallel execution async/resolve Background jobs Forks Threading
Structured command output stdout/stderr/status $? only Yes Yes

Ready to try
type-safe infrastructure?

Start with the language tour. Deploy with confidence.