Node API compatibility and imports
Scripting runs JavaScriptCore with a Node compatibility layer. This page describes the built-in modules registered by Scripting, their useful API subsets, and important limitations. The node command in Scripting's shell uses this environment; it does not launch a desktop Node executable. process.version / process.versions.node report a compatibility baseline, not complete support for that Node release. Availability in widgets, keyboards, Safari and isolated vm contexts can differ; the network examples linked here target full App scripts.
Where to import from
For registered built-ins, "net" and "node:net" resolve to the same module. A subpath needs its own registration: support for "stream" does not imply "stream/web". Both ES import syntax and CommonJS require() are supported through Scripting's module loader. Module evaluation uses CommonJS-style loading after transpilation; it is not a complete native Node ESM loader. Top-level await is supported in the script entry, not arbitrary required modules.
Each code block in the linked new API pages is an independent App script. Import declarations are at the top; awaiting work keeps its example active. Calling Script.exit() early closes owned resources and cancels pending timers.
Complete built-in-only example
This example needs no package installation, server or filesystem setup. It prints hello and its SHA-256 hexadecimal digest after a short delay.
Functional modules and implemented subsets
“Subset” means the listed operations work, with the limitations described here and in the linked reference. It does not promise every API of current Node. Table names can be used with the node: prefix.
Uppercase global Crypto operates on Scripting Data; lowercase global crypto is WebCrypto. For HKDF and the explicit ChaCha20-Poly1305 extension, use crypto.subtle / crypto.chacha20Poly1305, or import webcrypto from node:crypto. Do not assume createCipheriv("chacha20-poly1305", ...) or Node hkdfSync is provided. See HKDF/ChaCha and Curve25519.
Bonjour is a Scripting global, not a Node built-in; see its complete publish/browse/resolve example. The web-globals helper resource supplies globals internally; use the documented global APIs directly.
Importable compatibility placeholders
These modules can load so optional dependency paths can be detected, but their existence is not proof of functionality. Some operations throw; others return empty/no-op results.
dgram, inspector, repl and wasi reject when loaded. Other Node names or private internals absent from the registered inventory are unsupported, including domain, sys, trace_events, inspector/promises, assert/strict, path/posix, path/win32 and stream/web. A reserved resolver name or an editor completion is not an implementation.
Third-party npm packages
Use Tools → npm Packages or npm install <actual-package-name> in Scripting's shell. Pure-JavaScript parsers, formatters, validation and data-processing libraries are good candidates when their dependencies use the functional APIs above. Compatibility depends on the installed version, dependency tree and executed code path; there is no universal npm whitelist. Loading a package successfully does not verify its networking, subprocess or native paths.
Before adopting a package:
- Check its direct and transitive Node imports against this table, especially the placeholder section. A package that requires AsyncLocalStorage semantics, DNS queries, Worker or child processes needs a different code path.
- Prefer pure JavaScript distributions.
.nodenative addons, downloaded executables, browser automation engines and OS build tools cannot run through this compatibility layer. - Automatic dependency
preinstall/install/postinstall/preparescripts are skipped. Optional dependencies are not automatically installed. An installation can therefore succeed while an optional native feature is absent. - Run the actual operation and inspect its payload/result, errors and cleanup; do not stop at
require()success, an engine-version check ortypeof fn === "function". - Keep network/file permissions and iOS foreground/background limitations in mind. A package cannot acquire capabilities that its host script does not have.
For the complete callable signatures of the shipped subset, use Scripting's built-in TypeScript declarations and the linked API pages. This overview describes Scripting's implementations; it does not claim conformance to every API in desktop Node documentation.
