Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Install and run a first script

Add proc to your project:

deno add jsr:@j50n/proc

This records the package in deno.json, and from then on you import it by name. The core library is @j50n/proc; the data transforms (CSV, TSV, JSON lines) are a separate entry point, @j50n/proc/transforms, so you load them only if you use them.

import { enumerate, read, run } from "@j50n/proc";
import { fromCsvToRows, toTsv } from "@j50n/proc/transforms";

For a one-off script without a deno.json, import from JSR directly: import { run } from "jsr:@j50n/proc@0.29.0";.

A first script

Save this as errors.ts, next to a log file called app.log:

import { run } from "@j50n/proc";

const errors = await run("grep", "ERROR", "app.log").lines.collect();

console.log(`${errors.length} errors`);
for (const line of errors) {
  console.log(line);
}

Run it, allowing it to start grep:

deno run --allow-run=grep errors.ts
2 errors
2026-10-05 09:01:13 ERROR db: connection refused
2026-10-05 09:02:45 ERROR GET /orders/17 500

If app.log has no errors, grep exits with code 1, and the script stops with an ExitCodeError. That is proc treating a failed command as an error, the way set -e does in bash. Errors shows how to handle it.

Permissions

Deno asks before a script runs a program or touches a file. Grant only what the script needs:

The scriptNeeds
runs commands with run()--allow-run, or --allow-run=git,grep
reads files with read()--allow-read, or --allow-read=./logs
writes files with writeTo()--allow-write, or --allow-write=./out
uses only enumerate() and stepsnothing

A child inherits your environment. Passing env to run() adds or overrides variables for the child, and doesn’t need --allow-env.