Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
node-stdlib-browser
Advanced tools
The node-stdlib-browser package provides a browser-compatible implementation of Node.js's standard library modules. This allows developers to use Node.js core modules in a browser environment, facilitating the development of isomorphic (universal) JavaScript applications.
Buffer
The Buffer module provides a way to handle binary data in the browser, similar to how it's done in Node.js. This is useful for tasks like encoding and decoding data.
const { Buffer } = require('buffer');
const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex'));
Stream
The Stream module allows you to work with streaming data in the browser, similar to Node.js. This is useful for handling large amounts of data efficiently.
const { Readable } = require('stream');
const readable = new Readable();
readable._read = () => {}; // _read is required but you can noop it
readable.push('foo');
readable.push('bar');
readable.push(null);
readable.on('data', (chunk) => {
console.log(chunk.toString());
});
Crypto
The Crypto module provides cryptographic functionalities in the browser, such as hashing and encryption, similar to Node.js.
const { createHash } = require('crypto');
const hash = createHash('sha256');
hash.update('some data to hash');
console.log(hash.digest('hex'));
Browserify allows you to use Node.js modules in the browser by bundling up all of your dependencies. It transforms the Node.js require calls into browser-compatible code. Compared to node-stdlib-browser, Browserify is more focused on the bundling process and less on providing a direct implementation of Node.js's standard library.
Webpack is a module bundler that can also be configured to use Node.js modules in the browser. It has a rich plugin ecosystem and is highly configurable. While Webpack can achieve similar results, it is more complex and general-purpose compared to node-stdlib-browser, which is specifically designed to provide Node.js standard library modules in the browser.
Rollup is another module bundler that can be used to include Node.js modules in the browser. It is known for its tree-shaking capabilities, which help to reduce bundle size. Like Webpack, Rollup is more general-purpose and requires additional configuration to achieve the same functionality as node-stdlib-browser.
Node standard library for browser.
Features:
node-libs-browser
for Webpacknode:
protocol which
allows for builtin modules to be referenced by valid absolute URL stringsCheck example to see how modules work in browser environment.
npm install node-stdlib-browser --save-dev
As of Webpack 5, aliases and globals provider need to be explicitly configured.
If you want to handle node:
protocol imports, you
need to provide helper plugin.
// webpack.config.js
const stdLibBrowser = require('node-stdlib-browser');
const {
NodeProtocolUrlPlugin
} = require('node-stdlib-browser/helpers/webpack/plugin');
const webpack = require('webpack');
module.exports = {
// ...
resolve: {
alias: stdLibBrowser
},
plugins: [
new NodeProtocolUrlPlugin(),
new webpack.ProvidePlugin({
process: stdLibBrowser.process,
Buffer: [stdLibBrowser.buffer, 'Buffer']
})
]
};
If you’re using ESM config, additional configuration is needed to handle unspecified extensions:
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.m?js$/,
resolve: {
fullySpecified: false
}
}
]
}
};
Since many packages expose only CommonJS implementation, you need to apply plugins to handle CommonJS exports. Those packages could have dependencies installed with npm so they need to be properly resolved (taking into account browser-specific implementations).
Some dependencies can have circular dependencies and Rollup will warn you about that. You can ignore these warnings with helper function (reference).
// rollup.config.js
const stdLibBrowser = require('node-stdlib-browser');
const {
handleCircularDependancyWarning
} = require('node-stdlib-browser/helpers/rollup/plugin');
const { default: resolve } = require('@rollup/plugin-node-resolve');
const commonjs = require('@rollup/plugin-commonjs');
const json = require('@rollup/plugin-json');
const alias = require('@rollup/plugin-alias');
const inject = require('@rollup/plugin-inject');
module.exports = {
// ...
plugins: [
alias({
entries: stdLibBrowser
}),
resolve({
browser: true
}),
commonjs(),
json(),
inject({
process: stdLibBrowser.process,
Buffer: [stdLibBrowser.buffer, 'Buffer']
})
],
onwarn: (warning, rollupWarn) => {
handleCircularDependancyWarning(warning, rollupWarn);
}
};
Vite config uses combination of Rollup and esbuild plugins. It’s important to use dynamic import when using CommonJS configuration so ESM version of modules is picked up. This allows Vite bundling to use our mocking implementation and implement heuristics such as proper tree-shaking and dead code removal marking.
const inject = require('@rollup/plugin-inject');
const esbuildShim = require.resolve('node-stdlib-browser/helpers/esbuild/shim');
module.exports = async () => {
const { default: stdLibBrowser } = await import('node-stdlib-browser');
return {
resolve: {
alias: stdLibBrowser
},
optimizeDeps: {
include: ['buffer', 'process']
},
plugins: [
{
...inject({
global: [esbuildShim, 'global'],
process: [esbuildShim, 'process'],
Buffer: [esbuildShim, 'Buffer']
}),
enforce: 'post'
}
]
};
};
If you wish to use simpler configuration, you can use one of the available Vite plugins which use this package under the hood:
Using esbuild requires you to use helper utilities and plugins.
const path = require('path');
const esbuild = require('esbuild');
const plugin = require('node-stdlib-browser/helpers/esbuild/plugin');
const stdLibBrowser = require('node-stdlib-browser');
(async () => {
await esbuild.build({
// ...
inject: [require.resolve('node-stdlib-browser/helpers/esbuild/shim')],
define: {
global: 'global',
process: 'process',
Buffer: 'Buffer'
},
plugins: [plugin(stdLibBrowser)]
});
})();
Bundling ES modules is currently not supported natively in Browserify, but you can try using esmify or babelify for transforming to CommonJS first.
const fs = require('fs');
const path = require('path');
const browserify = require('browserify');
const aliasify = require('aliasify');
const stdLibBrowser = require('node-stdlib-browser');
const b = browserify(
[
/* ... */
],
{
// ...
transform: [[aliasify, { aliases: stdLibBrowser }]],
insertGlobalVars: {
process: () => {
return `require('${stdLibBrowser.process}')`;
},
Buffer: () => {
return `require('${stdLibBrowser.buffer}').Buffer`;
}
}
}
);
Module | Browser implementation | Mock implementation | Notes |
---|---|---|---|
assert | assert | ||
buffer | buffer | buffer | buffer@5 for IE 11 support |
child_process | |||
cluster | |||
console | console-browserify | console | |
constants | constants-browserify | ||
crypto | crypto-browserify | ||
dgram | |||
dns | dns | ||
domain | domain-browser | ||
events | events | ||
fs | Mocking fs | ||
http | stream-http | ||
https | https-browserify | ||
module | |||
net | net | ||
os | os-browserify | ||
path | path-browserify | ||
process | process | process | Contains additional exports from newer Node |
punycode | punycode | punycode@1 for browser support | |
querystring | querystring-es3 | Contains additional exports from newer Node versions | |
readline | |||
repl | |||
stream | stream-browserify | ||
string_decoder | string_decoder | ||
sys | util | ||
timers | timers-browserify | ||
timers/promises | isomorphic-timers-promises | ||
tls | tls | ||
tty | tty-browserify | tty | |
url | node-url | Contains additional exports from newer Node versions (URL and URLSearchParams are not polyfilled) | |
util | util | ||
vm | vm-browserify | ||
zlib | browserify-zlib | ||
_stream_duplex | readable-stream | ||
_stream_passthrough | readable-stream | ||
_stream_readable | readable-stream | ||
_stream_transform | readable-stream | ||
_stream_writable | readable-stream |
Returns: object
Exports absolute paths to each module directory (where package.json
is
located), keyed by module names. Modules without browser replacements return
module with default export null
.
Some modules have mocks in the mock directory. These are replacements with minimal functionality.
fs
fs
package doesn’t return anything since there are many different ways you can
implement file system functionality in browser.
Examples of implementations:
Minimum supported version should be Node 10.
If you’re using ESM in Node < 12.20, note that subpath patterns are not supported so mocks can’t be handled. In that case, it’s recommended to use CommonJS implementation.
Minimum supported version should be Internet Explorer 11, but most modules support even Internet Explorer 9.
You can use default @types/node
types.
MIT © Ivan Nikolić
FAQs
Node standard library for browser.
We found that node-stdlib-browser demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.