Skip to content

bootstrap: implement run-time user-land snapshots via --build-snapshot and --snapshot-blob

This patch introduces --build-snapshot and --snapshot-blob options for creating and using user land snapshots.

For the initial iteration, user land CJS modules and ESM are not yet supported in the snapshot, so only one single file can be snapshotted (users can bundle their applications into a single script with their bundler of choice to build a snapshot though).

A subset of builtins should already work, and support for more builtins are being added. This PR includes tests checking that the TypeScript compiler and the marked markdown renderer (and the builtins they use) can be snapshotted and deserialized.

To generate a snapshot using snapshot.js as entry point and write the snapshot blob to snapshot.blob:

$ echo "globalThis.foo = 'I am from the snapshot'" > snapshot.js
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js 

To restore application state from snapshot.blob, with index.js as the entry point script for the deserialized application:

$ echo "console.log(globalThis.foo)" > index.js
$ node --snapshot-blob snapshot.blob index.js
I am from the snapshot

Users can also use the v8.startupSnapshot API to specify an entry point at snapshot building time, thus avoiding the need of an additional entry script at deserialization time:

$ echo "require('v8').startupSnapshot.setDeserializeMainFunction(() => console.log('I am from the snapshot'))" > snapshot.js
$ node --snapshot-blob snapshot.blob --build-snapshot snapshot.js 
$ node --snapshot-blob snapshot.blob
I am from the snapshot

Note that this patch only adds functionality to the node executable for building run-time user-land snapshots, the generated snapshot is stored into a separate file on disk. Building a single binary with both Node.js and an embedded snapshot has already been possible with the --node-snapshot-main option to the configure script if the user compiles Node.js from source. It would be a different task to enable the node executable to produce a single binary that contains both Node.js and an embedded snapshot without building Node.js from source, which should be layered on top of the SEA (Single Executable Apps) initiative.

Known limitations/bugs that are being fixed in the V8 upstream:

More known limitations/bugs in the tracking issue: https://github.com/nodejs/node/issues/44014

Refs: https://github.com/nodejs/node/issues/35711

Merge request reports

Loading