New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@salve-software/nodeless

Package Overview
Dependencies
Maintainers
2
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@salve-software/nodeless

npm install and a React build, without Node. The same code in a server and in the browser: no shell, no filesystem, no VM.

Source
npmnpm
Version
0.0.0-development
Version published
Weekly downloads
1
-87.5%
Maintainers
2
Weekly downloads
 
Created
Source

nodeless

npm install and a React build, without Node

Version Downloads Node and browser No VM License

Give it a map of files. It installs the dependencies from npm and hands back index.html, bundle.js and bundle.css, all in memory and in the same process. No shell, no filesystem, no child process, no VM.

This works because a bundler never runs the code it bundles, and unpacking a tarball doesn't either. The container people spin up to build on demand is guarding a step that was already inert. Drop it and the same code runs on your server and in your user's browser.

An editor on the left, the built app running on the right

import { NodelessProject } from '@salve-software/nodeless';

const project = new NodelessProject({
  files: {
    '/package.json': '{ "dependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" } }',
    '/src/main.tsx': "import { createRoot } from 'react-dom/client'; /* ... */",
  },
});

await project.install();

const result = await project.build();

if (result.ok) {
  iframe.srcdoc = new TextDecoder().decode(result.files['index.html']);
} else {
  console.error(result.errors); // { text, file, line, column }
}

Features

  • Nothing gets executed. Not your files, not postinstall, not package.json scripts.
  • A real npm install. Semver ranges, integrity checks, npm's flat layout, a lockfile.
  • Works in the browser. A headless Chromium job in CI proves it, end to end.
  • Errors are data. Failed builds return { ok: false, errors } with file, line and column.
  • Fast enough to skip the dev server. About 200 ms for a React scaffold.
  • CSS modules built in, Tailwind if you want it. cssTransform hands stylesheets to PostCSS.
  • Preview before installing. build({ cdn }) points unresolved imports at a CDN.

Install

npm install @salve-software/nodeless

Node 20 or higher, or any browser with fetch and WebAssembly. The packages you build have to be pure JS.

Usage

Build

const result = await project.build({ mode: 'development' });

files comes back as Record<string, Uint8Array>. build() never writes to the VFS, which is what lets watch() run without a build triggering itself.

OptionDefault
entrythe first src/main.* that exists
mode'production'
html/index.html
outdir/dist
target'es2020'
conditionsbrowser, import, module, default
external[]
cdnoff

mode: 'development' turns minification off and inline sourcemaps on.

Install

const { installed, warnings, lockfile } = await project.install();

Reads dependencies from /package.json and writes the packages into /node_modules. Peer dependencies show up in warnings and are never installed for you. Only registry ranges work: npm:, file: and git+https: are refused rather than guessed.

In the browser

The published dist/ has four bare imports and needs no build step, so an import map covers it. Pass a wasmURL and the rest is identical.

<script type="importmap">
  {
    "imports": {
      "esbuild-wasm": "https://unpkg.com/esbuild-wasm@0.25.12/esm/browser.min.js",
      "resolve.exports": "https://esm.sh/resolve.exports@2.0.3",
      "semver": "https://esm.sh/semver@7.8.5",
      "fflate": "https://esm.sh/fflate@0.8.3"
    }
  }
</script>
new NodelessProject({
  files,
  wasmURL: 'https://unpkg.com/esbuild-wasm@0.25.12/esbuild.wasm',
});

esbuild-wasm runs its own worker, so the build doesn't block the UI.

Playground

npm run playground

An editor with a live preview next to it. It installs from npmjs.org in your browser, builds there, and renders the result. The other examples live in example/.

What it doesn't do

Native bindings, package.json scripts, postinstall, Rolldown, lightningcss, sharp, embedded sass, Tailwind v4, React Refresh. Most of that follows from the premise: a library that executed code would need isolation, and isolation is the cost this one exists to remove. Full reasoning in docs/design/06-scope-and-limits.md.

Docs, contributing, license

docs/design/ has the decisions behind the code. CONTRIBUTING.md has setup and conventions. MIT, see LICENSE.

Made by Salve Software

Keywords

bundler

FAQs

Package last updated on 11 Sep 2026

Related posts