From c7a3e61379a75094153092c016bcdf8e27e2ae15 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 05:16:06 +0000 Subject: [PATCH 1/5] docs(readme): add build-order and binary-anatomy diagrams Two SVG diagrams introduce engineers to the monorepo at a glance: build-tiers.svg shows how native libraries (curl + LIEF) flow up through stubs and the binary suite into the custom Node.js binary, and binary-anatomy.svg shows how a compressed on-disk stub decompresses into the runtime + SEA blob + VFS section in memory. Uses the Socket purple-to-pink brand gradient. --- README.md | 8 +++- docs/images/binary-anatomy.svg | 78 ++++++++++++++++++++++++++++++++ docs/images/build-tiers.svg | 82 ++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 docs/images/binary-anatomy.svg create mode 100644 docs/images/build-tiers.svg diff --git a/README.md b/README.md index 6900183e..103156f7 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,15 @@ Monorepo containing: - **WASM** - ONNX Runtime and Yoga Layout - **ML Models** - Quantized AI models (CodeT5, MiniLM) +The packages stack into four tiers — native libraries at the bottom, the custom Node.js binary at the top: + +![Build order: native libraries flow up into the final Node.js binary](docs/images/build-tiers.svg) + ## Core Concepts -If you're new to binary manipulation or Node.js customization, here are the key concepts you'll encounter: +If you're new to binary manipulation or Node.js customization, here are the key concepts you'll encounter. The diagram below shows how they compose into a final shipped artifact: + +![Anatomy of a Socket-built binary: a compressed stub on disk decompresses into a Node.js runtime that contains an SEA blob and a VFS section](docs/images/binary-anatomy.svg) ### Single Executable Application (SEA) diff --git a/docs/images/binary-anatomy.svg b/docs/images/binary-anatomy.svg new file mode 100644 index 00000000..c8ad0712 --- /dev/null +++ b/docs/images/binary-anatomy.svg @@ -0,0 +1,78 @@ + + Anatomy of a Socket-built binary + A small compressed binary on disk decompresses into a fully-loaded custom Node.js binary in memory, containing the runtime, an SEA blob, and a VFS section. + + + + + + + + + + + + + + + + + + + + + + Anatomy of a Socket-built binary + A small stub on disk decompresses into a fully-loaded Node.js runtime in memory. + + + + + Compressed binary + ~23 MB · ships to users + + + + Stub + self-extractor + links libcurl + mbedTLS + + + + zstd-compressed payload + opaque blob on disk + contains the binary on the right + + + + + decompresses to + + + + + Custom Node.js binary + ~60 MB · runs in memory + + + + Node.js runtime + v26 + Socket patches + node:smol-* built-ins + + + + SEA blob + your application's entry + Single Executable Application + + + + VFS section + embedded files + read via fs.readFile() + + + + binject inserts the SEA blob and VFS section · binpress wraps the result · binflate / the stub unwrap it at runtime + diff --git a/docs/images/build-tiers.svg b/docs/images/build-tiers.svg new file mode 100644 index 00000000..fc03aa23 --- /dev/null +++ b/docs/images/build-tiers.svg @@ -0,0 +1,82 @@ + + Socket BTM build order + Native libraries (curl, LIEF) build first, then stubs, then the binary suite (binject, binpress, binflate), then the custom Node.js binary. + + + + + + + + + + + + + + + + + + Build Order + Each tier depends on the tier above. Within a tier, packages build in parallel. + + + TIER 1 · NATIVE LIBRARIES + + + curl-builder + libcurl + mbedTLS + + + lief-builder + LIEF · Mach-O / ELF / PE + + + + + + + + TIER 2 · STUBS + + + stubs-builder + self-extracting stub binary + + + + + + + TIER 3 · BINARY SUITE + + + binject + inject data into binaries + + + binpress + zstd compress + + + binflate + decompress at runtime + + + + + + + + + TIER 4 · CUSTOM NODE.JS + + + node-smol-builder + Node.js v26 + Socket security patches + node:smol-* built-ins · VFS · SEA + + + Skipping a tier or dispatching out of order is gated by scripts/check-publish-prereq.mts + From ef10d4f336436fec49935028150921d034358b16 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 05:45:36 +0000 Subject: [PATCH 2/5] docs(readme): flip build-tiers diagram to put node-smol at top Match the surrounding prose, which puts native libraries at the bottom and the custom Node.js binary at the top. Arrows now point upward, gradient runs pink-at-top to purple-at-bottom so each tier keeps its identity color (T4 pink, T1 purple). --- docs/images/build-tiers.svg | 93 +++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/docs/images/build-tiers.svg b/docs/images/build-tiers.svg index fc03aa23..3a298adf 100644 --- a/docs/images/build-tiers.svg +++ b/docs/images/build-tiers.svg @@ -1,6 +1,6 @@ Socket BTM build order - Native libraries (curl, LIEF) build first, then stubs, then the binary suite (binject, binpress, binflate), then the custom Node.js binary. + Native libraries (curl, LIEF) at the bottom build first, then stubs, then the binary suite (binject, binpress, binflate), then the custom Node.js binary at the top. @@ -8,8 +8,8 @@ - - + + @@ -19,64 +19,65 @@ Build Order - Each tier depends on the tier above. Within a tier, packages build in parallel. + Native libraries at the bottom flow up into the custom Node.js binary at the top. - - TIER 1 · NATIVE LIBRARIES + + TIER 4 · CUSTOM NODE.JS - - curl-builder - libcurl + mbedTLS - - - lief-builder - LIEF · Mach-O / ELF / PE + + node-smol-builder + Node.js v26 + Socket security patches + node:smol-* built-ins · VFS · SEA - - - + + + + - - TIER 2 · STUBS + + TIER 3 · BINARY SUITE - - stubs-builder - self-extracting stub binary + + binject + inject data into binaries + + + binpress + zstd compress + + + binflate + decompress at runtime - + - - TIER 3 · BINARY SUITE + + TIER 2 · STUBS - - binject - inject data into binaries - - - binpress - zstd compress - - - binflate - decompress at runtime + + stubs-builder + self-extracting stub binary - - - - + + + - - TIER 4 · CUSTOM NODE.JS + + TIER 1 · NATIVE LIBRARIES - - node-smol-builder - Node.js v26 + Socket security patches - node:smol-* built-ins · VFS · SEA + + curl-builder + libcurl + mbedTLS + + + lief-builder + LIEF · Mach-O / ELF / PE - Skipping a tier or dispatching out of order is gated by scripts/check-publish-prereq.mts + Read bottom to top to follow build order. Within a tier, packages build in parallel. + Skipping a tier or dispatching out of order is gated by scripts/check-publish-prereq.mts. From a9ee5dcadc3ef1af531526041972f20695a452bb Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 06:06:18 +0000 Subject: [PATCH 3/5] docs(readme): correct binary-anatomy diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The whole shipped binary IS the SEA — make that explicit in the right-hand box label. Mark the compressed launcher as optional (produced by binpress) since the default node-smol-builder build is the raw runtime. Clarify the stub's role (zstd decompressor; libcurl + mbedTLS is for optional update checks, not for the decompression itself). Note that the SEA blob and VFS section are siblings injected side-by-side by binject. --- docs/images/binary-anatomy.svg | 72 +++++++++++++++++----------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/docs/images/binary-anatomy.svg b/docs/images/binary-anatomy.svg index c8ad0712..0091e6e7 100644 --- a/docs/images/binary-anatomy.svg +++ b/docs/images/binary-anatomy.svg @@ -1,6 +1,6 @@ - + Anatomy of a Socket-built binary - A small compressed binary on disk decompresses into a fully-loaded custom Node.js binary in memory, containing the runtime, an SEA blob, and a VFS section. + A Single Executable Application (the SEA) is the whole shipped binary: a Node.js runtime with two injected sections, the SEA blob and a VFS section. binpress optionally wraps it in a stub for smaller distribution. @@ -20,59 +20,61 @@ - + Anatomy of a Socket-built binary - A small stub on disk decompresses into a fully-loaded Node.js runtime in memory. + The whole shipped binary IS the SEA. binpress optionally wraps it in a stub for smaller distribution. - + - - Compressed binary - ~23 MB · ships to users + + Compressed launcher + optional · ~23 MB · produced by binpress - - Stub - self-extractor - links libcurl + mbedTLS + + Stub + tiny zstd decompressor + libcurl + mbedTLS for update checks - - zstd-compressed payload - opaque blob on disk - contains the binary on the right + + zstd-compressed payload + opaque blob on disk + = the binary on the right - decompresses to + decompresses + execs - + - - Custom Node.js binary - ~60 MB · runs in memory + + Single Executable Application + the SEA · ~60 MB · what your users run - - - Node.js runtime - v26 + Socket patches - node:smol-* built-ins + + + Node.js runtime + v26 + Socket patches + node:smol-* built-ins - - SEA blob - your application's entry - Single Executable Application + + SEA blob + JS app entry + sea-config.json + executed on startup - - VFS section - embedded files - read via fs.readFile() + + VFS section + embedded files (tar.gz) + read via fs.readFile() + + SEA blob + VFS injected side-by-side by binject - binject inserts the SEA blob and VFS section · binpress wraps the result · binflate / the stub unwrap it at runtime + node-smol-builder produces the raw runtime. binject injects the SEA blob and VFS. binpress (optional) compresses for distribution. From e2776bcfa46eacc83776fea22f574922a1c7b27b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 06:09:35 +0000 Subject: [PATCH 4/5] docs(readme): drop inconsistent arrows from build-tiers diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arrows in the previous version mixed two semantics: the bottom two (curl/lief into stubs) were real code dependencies, but the upper arrows (stubs into binsuite, binsuite into node-smol) were not — node-smol doesn't depend on the binary suite, and binject / binflate don't depend on stubs. The four-tier model is a publish dispatch order (cache cascade for releases), not a strict dependency DAG. Drop the arrows entirely; let the visual stacking carry the meaning, and have the subtitle state exactly what the stacking represents. Every visual element now has one consistent meaning. --- docs/images/build-tiers.svg | 85 ++++++++++++++----------------------- 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/docs/images/build-tiers.svg b/docs/images/build-tiers.svg index 3a298adf..ae2a12a6 100644 --- a/docs/images/build-tiers.svg +++ b/docs/images/build-tiers.svg @@ -1,83 +1,64 @@ - + Socket BTM build order - Native libraries (curl, LIEF) at the bottom build first, then stubs, then the binary suite (binject, binpress, binflate), then the custom Node.js binary at the top. + Four tiers of packages stacked vertically. Native libraries (curl, LIEF) at the bottom, custom Node.js binary at the top. Re-publishing any tier requires re-publishing every tier above it. - - - - - - - - + Build Order - Native libraries at the bottom flow up into the custom Node.js binary at the top. + Native libraries at the bottom, custom Node.js at the top. + Re-publishing any tier cascades upward — every tier above it must republish too. - TIER 4 · CUSTOM NODE.JS + TIER 4 · CUSTOM NODE.JS - - node-smol-builder - Node.js v26 + Socket security patches - node:smol-* built-ins · VFS · SEA + + node-smol-builder + Node.js v26 + Socket security patches + node:smol-* built-ins · VFS · SEA - - - - - - TIER 3 · BINARY SUITE + TIER 3 · BINARY SUITE - - binject - inject data into binaries + + binject + inject data into binaries - - binpress - zstd compress + + binpress + zstd compress - - binflate - decompress at runtime + + binflate + decompress at runtime - - - - TIER 2 · STUBS + TIER 2 · STUBS - - stubs-builder - self-extracting stub binary + + stubs-builder + self-extracting stub binary - - - - - - TIER 1 · NATIVE LIBRARIES + + TIER 1 · NATIVE LIBRARIES - - curl-builder - libcurl + mbedTLS + + curl-builder + libcurl + mbedTLS - - lief-builder - LIEF · Mach-O / ELF / PE + + lief-builder + LIEF · Mach-O / ELF / PE - Read bottom to top to follow build order. Within a tier, packages build in parallel. - Skipping a tier or dispatching out of order is gated by scripts/check-publish-prereq.mts. + Skipping a tier or dispatching out of order is gated by scripts/check-publish-prereq.mts. From 8b08db1ff4891105a2367ee05c8981dcf97405e8 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 06:19:34 +0000 Subject: [PATCH 5/5] docs(readme): redesign binary diagrams for beginners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes pitched at engineers new to binary manipulation: 1. Rewrite the binary-anatomy diagram as a CONSTRUCTION view — shows binject's action explicitly (inputs on the left, the merged SEA on the right) with a clear visual language: solid borders for real files on disk, dashed borders for virtual files embedded inside the binary. The VFS section now lists concrete example files so it's obvious what 'embedded files' means in practice. 2. Add a new lifecycle diagram showing what actually happens at run time — stub decompresses, runtime boots and reads the SEA blob + VFS, app produces output. Action-labeled arrows between three stages (on disk · in memory · output). --- README.md | 10 ++- docs/images/binary-anatomy.svg | 155 +++++++++++++++++++-------------- docs/images/lifecycle.svg | 76 ++++++++++++++++ 3 files changed, 172 insertions(+), 69 deletions(-) create mode 100644 docs/images/lifecycle.svg diff --git a/README.md b/README.md index 103156f7..3e053780 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ The packages stack into four tiers — native libraries at the bottom, the custo ## Core Concepts -If you're new to binary manipulation or Node.js customization, here are the key concepts you'll encounter. The diagram below shows how they compose into a final shipped artifact: +If you're new to binary manipulation or Node.js customization, here are the key concepts you'll encounter. The diagram below shows how `binject` merges your app with the Node.js runtime to produce a Single Executable Application — solid borders are real files on disk, dashed borders are virtual files embedded inside the binary: -![Anatomy of a Socket-built binary: a compressed stub on disk decompresses into a Node.js runtime that contains an SEA blob and a VFS section](docs/images/binary-anatomy.svg) +![How a Socket binary is built: binject merges the Node.js runtime with your app's source files into a SEA containing a runtime, an SEA blob, and a VFS section](docs/images/binary-anatomy.svg) ### Single Executable Application (SEA) @@ -76,6 +76,12 @@ Reducing binary size for distribution. Compressed binaries self-extract at runti **Example:** 60MB Node.js binary → 23MB compressed binary (saves bandwidth, faster downloads). +### Putting it together: what happens when a user runs the binary + +The stub decompresses the zstd payload, the Node.js runtime boots and reads the SEA blob to find the entry point, and the running app reads VFS files via `fs.readFile()` like they were on disk: + +![Runtime lifecycle: stub decompresses, runtime executes the SEA blob and reads VFS, your app produces output](docs/images/lifecycle.svg) + ## Quick Start `binject` / `binpress` depend on a prebuilt LIEF artifact, and `stubs-builder` depends on prebuilt curl+mbedTLS; both are fetched automatically from this repo's GitHub releases on first build. Pass `pnpm --filter run build -- --force` if you need to compile those libraries from source (e.g. an unsupported platform or a LIEF/curl bump that hasn't been published yet). diff --git a/docs/images/binary-anatomy.svg b/docs/images/binary-anatomy.svg index 0091e6e7..3e35d225 100644 --- a/docs/images/binary-anatomy.svg +++ b/docs/images/binary-anatomy.svg @@ -1,80 +1,101 @@ - - Anatomy of a Socket-built binary - A Single Executable Application (the SEA) is the whole shipped binary: a Node.js runtime with two injected sections, the SEA blob and a VFS section. binpress optionally wraps it in a stub for smaller distribution. + + How a Socket binary is built + binject merges a Node.js runtime with your app's source files into a Single Executable Application. Solid borders are real files on disk; dashed borders are virtual files embedded inside the binary. - + - - + + - - + + - - + + - - - Anatomy of a Socket-built binary - The whole shipped binary IS the SEA. binpress optionally wraps it in a stub for smaller distribution. - - - - - Compressed launcher - optional · ~23 MB · produced by binpress - - - - Stub - tiny zstd decompressor - libcurl + mbedTLS for update checks - - - - zstd-compressed payload - opaque blob on disk - = the binary on the right - - - - - decompresses + execs - - - - - Single Executable Application - the SEA · ~60 MB · what your users run - - - - Node.js runtime - v26 + Socket patches - node:smol-* built-ins - - - - SEA blob - JS app entry + sea-config.json - executed on startup - - - - VFS section - embedded files (tar.gz) - read via fs.readFile() - - SEA blob + VFS injected side-by-side by binject - - - - node-smol-builder produces the raw runtime. binject injects the SEA blob and VFS. binpress (optional) compresses for distribution. + + + How a Socket binary is built + binject merges the Node.js runtime with your app's files into one Single Executable Application. + + + INPUTS · ON DISK + + + Node.js binary + raw, no app yet + from node-smol-builder + + + + + + your app + files + + + index.js + + + sea-config.json + + + node_modules/ + + + assets/icon.png + + …and any other files + + + + binject + compiles entry → SEA blob + tars files → VFS section + injects both into the binary + + + OUTPUT · ONE BINARY + + + Single Executable Application (SEA) + + + + Node.js runtime + v26 + Socket patches · node:smol-* built-ins + + + SEA BLOB · executed on startup + + index.js (bytecode) + + sea-config.json + + + VFS SECTION · read via fs.readFile() + + package.json + + node_modules/ + + assets/ + + + lib/util.js + + templates/ + + + + these look like real files to your code · fs.readFile('package.json') just works + stored as a tar.gz · ungzipped lazily by node:smol-vfs + + + Legend: solid borders = real files on disk · dashed borders = virtual files embedded inside the binary. diff --git a/docs/images/lifecycle.svg b/docs/images/lifecycle.svg new file mode 100644 index 00000000..7682afc0 --- /dev/null +++ b/docs/images/lifecycle.svg @@ -0,0 +1,76 @@ + + What happens when you run a Socket binary + Three stages: the stub unpacks the compressed binary, the Node.js runtime boots and reads the SEA blob and VFS, and your app produces output. + + + + + + + + + + + + + + + + + + + + + + + + + + What happens when you run a Socket binary + Three stages: the stub unpacks, the runtime boots, your app produces output. + + + 1 · ON DISK + + compressed binary + ~23 MB · what the user downloads + + + stub + + + zstd payload + + + + stub: zstd-decompress + exec inner binary + + + 2 · IN MEMORY · THE SEA + + Single Executable Application + + + Node.js runtime · v26 + Socket patches + + + SEA blob (entry bytecode + config) + + + VFS section (embedded files) + + runtime boots · reads SEA blob to find the entry · serves VFS to fs.readFile() + + + + runtime executes the entry · your app code runs + + + 3 · ✨ OUTPUT + + your app's output + scan complete · 0 critical · 2 medium + whatever your CLI prints + + +