
# Installation

> Build the nstd executable from source and check that it works.

There is no download yet. No prebuilt binary is published anywhere for nstd,
and nothing in this project's CI builds or releases one. The
[`nstdlib`](https://www.npmjs.com/package/nstdlib) library published on npm is
not the same thing as this binary. Today, building from source is the only way
to get nstd.

## Prerequisites

- **[Zig](https://ziglang.org/) 0.16.0.** This is a hard requirement, pinned
  in the build config, not just a recommendation.
- **Node.js**, matching the version in this repository's `.nvmrc`
  (currently `26.7.0`). The build reads information out of the exact Node
  version it runs under to generate parts of the standard library, so a
  mismatched Node produces a broken build. If your default `node` is a
  different version, install a matching one and use that.
- **[pnpm](https://pnpm.io/)**, via Corepack. `corepack enable` is enough if
  you don't already have it.
- **Git**, with the ability to fetch this repository's submodule (a pinned
  checkout of Node's own source, which the build reads from).

## Build from source

Clone the repository and fetch its submodule:

```sh
git clone https://github.com/unjs/nstd.git
cd nstd
git submodule update --init --depth 1
```

Install dependencies:

```sh
corepack enable
pnpm install
```

Build nstdlib itself first. This produces `./dist`, the standard library
that gets embedded into the binary:

```sh
pnpm build
```

Then build the native runtime:

```sh
pnpm --filter nstdlib-native build
```

This stages `./dist` into `native/assets/`, then runs a Zig release build.
The finished binary lands at `native/zig-out/bin/nstd`. Plain `zig build`
with no flags produces an unoptimized debug binary instead, so use the pnpm
script above rather than calling Zig directly, unless you specifically want
a debug build to chase down a Zig-level crash.

## Check it worked

```sh
./native/zig-out/bin/nstd -e 'console.log(1 + 1)'
./native/zig-out/bin/nstd --print-realm
```

The first line should print `2`. `--print-realm` prints how many of Node's
builtin modules (`fs`, `http`, `path`, and so on) registered successfully in
this build; it should report every one of them available and none missing.

From here, try running a real script:

```sh
./native/zig-out/bin/nstd my-script.js
```

## Building for wasm32-wasi

A WASI build is real and produces a working binary, booting the same standard
library as the native build:

```sh
pnpm --filter nstdlib-native build:wasm
```

This produces `native/zig-out/bin/nstd.wasm`, which runs under any
WASI-compatible runtime, for example `wasmtime`:

```sh
wasmtime native/zig-out/bin/nstd.wasm -- --print-realm
```

Two things are missing from this build. Networking is unavailable on every
wasm target, so `net`, `http` and `fetch` answer `ENOSYS` rather than opening
a connection, and `fs.watch()` needs `inotify`, so it is refused by name.
Everything else boots the same as the native build.

This target is also a step toward running nstd inside a browser, though not
the final form of that: three pieces (exiting the process, the wait the event
loop does, and file access) still assume a WASI-style host and would need to
be swapped out.

## Next

Once you have a working binary, [Running Code](/guide/usage) covers actually
using it, and [CLI Options](/guide/cli) documents the flags it accepts.
