new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · all subjects

runtime/process

37 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

SIGINT handler example

process.on("SIGINT", () => { console.log("Ctrl-C was pressed"); process.exit(); });

Listen for SIGINT (Ctrl+C) signal

The ctrl+c shortcut sends an interrupt signal to the running process. Intercept it by listening for the 'SIGINT' event using process.on(). To close the process, you must explicitly call process.exit().

Bun.argv contains argument vector

The argument vector passed to a program is available as Bun.argv. It is an array that includes the path to the Bun executable, the path to the script, and all command-line arguments passed after the script name.

parseArgs from util module

Use util.parseArgs() to parse Bun.argv into a more useful format. It takes an options object with 'args' (the argv array), 'options' (object defining flag types), 'strict' (boolean), and 'allowPositionals' (boolean). It returns an object with 'values' (parsed flags) and 'positionals' (remaining positional arguments).

parseArgs example with boolean and string flags

Example code: import { parseArgs } from "util"; const { values, positionals } = parseArgs({ args: Bun.argv, options: { flag1: { type: "boolean" }, flag2: { type: "string" } }, strict: true, allowPositionals: true }); console.log(values); console.log(positionals); This parses --flag1 as a boolean and --flag2 as a string, outputting values as { flag1: true, flag2: "value" } and positionals as [ "/path/to/bun", "/path/to/cli.ts" ].

Bun.argv example with arguments

When running `bun run cli.ts --flag1 --flag2 value`, Bun.argv contains: [ "/path/to/bun", "/path/to/cli.ts", "--flag1", "--flag2", "value" ]

Bun.nanoseconds() returns process uptime in nanoseconds

Bun.nanoseconds() returns the total number of nanoseconds the bun process has been alive. Call it with no arguments: Bun.nanoseconds()

process.on() supports OS signals

Bun supports the Node.js process global, including the process.on() method for listening to OS signals. For example, process.on("SIGINT", () => { console.log("Received SIGINT"); }) listens for the SIGINT signal.

process.on("beforeExit") event

The process.on("beforeExit", code => { ... }) event fires when the event loop is empty. This can be used as a fallback if you don't know which specific signal to listen for.

process.on("exit") event

The process.on("exit", code => { console.log(`Process is exiting with code ${code}`); }) event fires when the process is about to exit. The code parameter is the exit code of the process.

Interactive stdin prompt with console AsyncIterable example

The following code creates an interactive prompt that reads lines from stdin and echoes them back: ```ts const prompt = "Type something: "; process.stdout.write(prompt); for await (const line of console) { console.log(`You typed: ${line}`); process.stdout.write(prompt); } ```

console object is AsyncIterable for stdin lines

In Bun, the console object is an AsyncIterable that yields lines from stdin. You can use a for-await loop to iterate over console and receive input line by line.

Bun.stdin is a BunFile for reading piped input

Bun exposes stdin as a BunFile through Bun.stdin. You can use it to incrementally read large inputs piped into the bun process.

Bun.stdin.stream() chunks are not guaranteed to be line-split

When using Bun.stdin.stream() to iterate over chunks, chunks are not guaranteed to be split line-by-line. Each chunk is a Uint8Array.

Reading piped stdin as chunks with Bun.stdin.stream() example

The following code reads chunks from piped input and converts them to text: ```ts for await (const chunk of Bun.stdin.stream()) { // chunk is Uint8Array // this converts it to text (assumes ASCII encoding) const chunkText = Buffer.from(chunk).toString(); console.log(`Chunk: ${chunkText}`); } ```

--minify-syntax flag collapses if statements

When --minify-syntax (or --minify) is passed, Bun collapses the if statement scaffolding after dead code elimination. For example, an if statement with only one reachable branch becomes just the statement itself: bun build --define process.env.NODE_ENV="'production'" --minify-syntax src/index.ts.

--define versus setting a variable

Setting a variable like process.env.NODE_ENV in code does not enable dead code elimination because property accesses can have side effects (getters, setters, dynamic definitions via prototype chains or Proxy). Static analysis cannot assume the value remains the same on the next line. The --define flag provides a compile-time guarantee that enables optimizations.

--define replacing properties

The --define flag can replace property accesses with other values. For example: bun --define console.write=console.log src/index.ts replaces all console.write calls with console.log.

--define flag for static constants

The --define flag declares statically-analyzable constants and globals that replace all usages of an identifier or property in JavaScript or TypeScript files with a constant value. It works both at runtime (bun --define) and in builds (bun build --define). It is similar to #define in C/C++ but for JavaScript.

--define enables dead code elimination

Bun uses statically-known values defined with --define for dead code elimination and other optimizations. For example, when process.env.NODE_ENV is defined as 'production', the transpiler replaces the identifier with the literal value and can eliminate unreachable code branches.

--define supports multiple value types

The --define flag can replace identifiers with strings, other identifiers, properties, or JSON values. String values require shell escaping. Identifiers do not need quotes. JSON objects and arrays are supported and are transformed to equivalent JavaScript code.

--define replacing global identifiers

To replace all usages of a global identifier, pass it to --define. For example: bun --define window="undefined" src/index.ts replaces all window references with undefined. This is useful for server-side rendering or to ensure code doesn't depend on the window object.

--define replacing one identifier with another

Identifiers can be replaced with other identifiers. For example: bun --define global="globalThis" src/index.ts replaces all usages of global with globalThis. This is useful because global is available in Node.js but not in web browsers.

--define replacing with JSON objects

To replace an identifier with a JSON object, use: bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts. Bun transforms the JSON into equivalent JavaScript object literal code. For example, AWS.ACCESS_KEY becomes { ACCESS_KEY: "abc", SECRET_KEY: "def" }.ACCESS_KEY.

--define operates on AST not text

The --define flag operates on the Abstract Syntax Tree (AST) during transpilation, not on text. This means it participates in optimizations like dead code elimination and avoids escaping issues and unintended replacements that can occur with string replacement tools.

process.env access

Access the current environment variables with process.env. For example, process.env.API_TOKEN returns the value of the API_TOKEN environment variable.

Bun.env alias for process.env

Bun exposes Bun.env as an alias of process.env. Both provide the same access to environment variables.

Access environment variables with process.env and Bun.env

Environment variables can be accessed in two ways: using process.env.VARIABLE_NAME or Bun.env.VARIABLE_NAME. Both methods return the same value.

Setting TZ on command line

Set the timezone when running a Bun command by prefixing it with the TZ environment variable, for example: TZ=America/New_York bun run dev

Setting TZ programmatically in code

Set the timezone by assigning a time zone identifier to process.env.TZ from within code, for example: process.env.TZ = "America/New_York";

Setting timezone with TZ environment variable

Bun supports setting a default time zone for the lifetime of the process by setting the TZ environment variable to a valid time zone identifier from the IANA time zone database.

Default timezone in bun run

When running a file with bun, the time zone defaults to the system's configured local time zone.

Default timezone in bun test

When running tests with bun test, the time zone is set to UTC to make tests more deterministic.

Date instances respect TZ setting

Once TZ is set in the process environment, every Date instance created uses that time zone. For example, if the system time is 6:00 PM UTC, new Date().getHours() will return 18 without TZ set, but will return 21 after setting TZ to America/New_York.

import.meta.main to check if current file is entrypoint

Use import.meta.main to check if the current file is the entrypoint of the current process. When true, the file is directly executed with 'bun run'. When false, the file is being imported by another file.

Check entrypoint example

if (import.meta.main) { // this file is directly executed with `bun run` } else { // this file is being imported by another file }

import.meta.path returns absolute path of current file

import.meta.path retrieves the absolute path of the current file. When used in a file at /a/b/c.ts, import.meta.path returns the string "/a/b/c.ts".

Give your agent this brain