---
title: Native Program Objects
url: "https://scriptc.dev/docs/native-objects"
docs_index: /llms.txt
lastUpdated: 2026-10-18
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

A native program object lets your own build system link a compiled program, for example to combine it with other native code in Xcode, CMake, or a custom linker command. `scriptc build --emit=obj` writes one relocatable object file that defines `main`, without running a compiler, linker, or SDK. To build a library that a host application calls into instead, use library mode (`scriptc build --lib --profile`).

## ABI and runtime contract

The object format is experimental and can change in any release before 1.0. Link an object only with the runtime pack from the same scriptc installation, which `--print=native-link-info` reports.

The object leaves the runtime functions it uses undefined, for the runtime pack to provide. It also references a versioned marker symbol that only the matching runtime defines, so linking against a different runtime version fails at link time instead of misbehaving at runtime.

## Machine-readable link information

Add `--print=native-link-info` to write the object and print a JSON link recipe instead of the output path:

```console
$ scriptc build main.ts --print=native-link-info -o app.o > link-info.json
```

The `scriptc.native-link-info.v1` document reports:

- target triple, object format, architecture, minimum OS, and relocation model;
- the `main` entry and the runtime marker symbol;
- the matching installed precompiled runtime-pack root, selected objects and archives, sizes, and hashes;
- ordered program, FFI, runtime, and vendor inputs; and
- required system libraries and frameworks.

Runtime artifact paths are relative to `runtime_pack.root`, and FFI library paths are absolute. Link the inputs in the order the document lists them.

## C compiler as linker driver

The repository's [`examples/native-object`](https://github.com/vercel-labs/scriptc/tree/main/examples/native-object) directory contains a TypeScript program, a C function it calls through [FFI](/docs/ffi), and a small script that links them using the JSON recipe:

```console
$ cd examples/native-object
$ clang -target arm64-apple-macosx14.0.0 -O2 -c native.c -o native.o
$ scriptc build main.ts --ffi ffi.json --print=native-link-info -o app.o > link-info.json
$ node link.mjs cc link-info.json app-cc
$ ./app-cc
42
```

The script passes clang the reported objects, archives, and system libraries. On other targets, use a linker and sysroot for that target: glibc or musl for Linux, zig's MinGW sysroot for Windows x64, and a WASI Preview 1 sysroot for WASI.

## Native Apple linker

The same example can invoke Apple `ld` directly with the precompiled runtime objects:

```console
$ node link.mjs ld link-info.json app-ld
$ ./app-ld
42
```

In this mode the script asks `xcrun` for the macOS SDK and linker, then passes the target's minimum OS version, every object and archive in order, and each reported system library. scriptc produces `app.o`; your toolchain performs the link.

FFI bindings behave the same in program objects as in executables, following the [Native FFI](/docs/ffi) manifest.

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)