
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
neo-builder
Advanced tools
the fastest tiny script packager written in javascript and supporting iife dynamic chaining w/o extra runtime
The simplest javascript builder based on regular expressions, started as research project
node_modules (reexports, direct imports from node-modules, etc)esbuild or vite in release mode).pnpm supportBenchmarks of various popular bundlers for random packages:
| package | webpack | neo-builder | esbuild | parcel |
|---|---|---|---|---|
| @uppy/dashboard | 1272ms | 67ms | 47ms | - |
| @codemirror/lang-javascript | 1513ms | 70ms | 68ms | 75ms |
| codemirror | 1520ms | 77ms | 72ms | 81ms |
| msw | 1179ms | 32ms | 48ms | 265ms |
| swiper | 911ms | 26ms | 27ms | 86ms |
A comparative table of the sizes of the received bundles allows us to indirectly draw conclusions about the quality of the builder's three shaking feature:
| package | webpack | neo-builder* | esbuild | parcel |
|---|---|---|---|---|
| @uppy | 371 kb | 382 kb | 346 kb | - |
| @codemirror-javascript | 1016 kb | 1040 kb | 649 kb | 942 kb |
| codemirror | 1007 kb | 1034 kb | 751 kb | 942 kb |
| msw | 85 kb | 72 kb | 66 kb | 1184 kb |
| swiper | 303 kb | 170 kb | 166 kb | 342 kb |
| The same packages minified: | ||||
| @uppy/dashboard | 181kb | 182kb | 179kb | - |
| @codemirror/lang-javascript | 326kb | 360kb | 322kb | 433kb |
| codemirror | 344kb | 344kb | 338kb | 391kb |
| msw | 27kb | 22kb | 27kb | error |
| swiper | 77kb | 75kb | 75kb | 164kb |
import * as module, defaultImport from 'module') because of unuselessness.
At last what is the reason to import default when module at the same time consists of the default?)local
npm i neo-builder -D --omit=dev
or global
npm i neo-builder -g
neo index.js -t target.js --time
-s - source file name (could be passed as first arg without the flag -s)-t - target file name (required)-m - generate sourcemap file (optional)--time - verbose build time (optional)const packFile = require('neo-builder').packFile
let r = packFile(sourceFile, targetFile, {
// options
});
release? - remove one line comments and plain console.log expressionspurgeDebug? - remove /**@debug*/ ... /**@end_debug*/ code blocksgetContent? - custom getContent implementationlogStub? - logs with source filename and line in runtimesourceMaps?: { encode: Function, external?: true } - option for source map passing the encode method from the sourcemap-codec library or its independent implementation. Look tests for examplegetSourceMap?: Function - an alternative method for obtaining unencrypted line-by-line source maps for its further programmatic use (works 30% faster than the classical generation of char by char sourcemaps)__common.ts file:
let r = 7
function asd(){}
export let months = ['Jan', 'Feb', 'Mar', 'Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
export var a = 6;
export function Ads(arg){}
export class Asde{}
and init.ts:
import * as com from "./__common"
var a = com.a;
var c = 7540;
turn out the content inside init.js in the same directory:
//@modules:
const $$__commonExports = (function (exports) {
let r = 7
function asd() { }
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var a = 6;
function Ads(arg) { }
class Asde { }
exports = { months, a, Ads, Asde };
return exports
})({})
//@init.ts:
const com = $$__commonExports;
var a = com.a;
var c = 7540;
Neo-builder supports dynamic imports (with iife) under browser mode out of the box, what makes it unique. Let's consider the following code:
const langs = ['python', 'javascript'];
for (const key in langs) {
const lang = langs[key];
import(`@codemirror/lang-${lang}`).then(exp => {
console.log(exp[lang]());
})
}
It'll be built into the following code:
const langs = ['python', 'javascript'];
for (const key in langs) {
const lang = langs[key];
fetch(`./dist/$_lang-${lang}_1702744262895.js`).then(r => r.text()).then(content => new Function(content)()).then(exp => {
console.log(exp[lang]());
})
}
Simultaneously it'll build relevant files into the distination folder ($_lang-javascript_1702744262895.js and $_lang-python_1702744262895.js). But be careful: this files will be created at the same folder where main app file is built. If you want to manage path, specified into the fetch request, you should use advanced.dynamicImportsRoot option in your build config.
As you can see, in the example above it is used variable inside template string. Neo-builder supports variables by dynamic imports out of the box and allows import packages directly from node_modules. These features also unique feature at this time (mainstream builders haven't variables support out of the box, and direct imports from node_modules haven't support, at all). But you should be awared there are limitations of the usage:
Tree shaking cuts unused functions from code bundle. But by default is disabled (because of in alpha). To use it, set advanced.treeShaking option into true.
Consider following files:
import { default as A } from "./routes";
console.log(A)
function _func(params) {
return params.length
}
export function func() {
return _func(arguments);
}
function createArray(length) {
return Array(length)
}
export default function() {
return createArray(0);
}
With enabled treeShaking unused functions _func and func will be cutted in the resulting bundle:
const $__routesExports = (function (exports) {
function createArray(length) {
return Array(length)
}
function $default() {
return createArray(0);
}
exports = { default: $default };
return exports
})({})
neo-builder also supports custom plugins. Below there is example how itcan be used:
const uglify = require("uglify-js");
const neoMinify = {
name: 'neo-minify-plugin',
bundle: (/** @type {string} */ code, { maps, rawMap }) => {
const result = uglify.minify({ target: code }, {
sourceMap: sourcemap ? {
content: JSON.stringify(maps),
url: sourcemapInline ? "inline" : (target + ".map")
} : undefined
});
if (sourcemap && !sourcemapInline) {
fs.writeFileSync(target + '.map', result.map)
// fs.writeFileSync(target + '.map', JSON.stringify(result.map))
}
return result.code
}
}
let r = packFile(sourceFile, targetFile, {
// options
plugins: [neoMinify]
});
FAQs
the fastest tiny script packager written in javascript and supporting iife dynamic chaining w/o extra runtime
The npm package neo-builder receives a total of 69 weekly downloads. As such, neo-builder popularity was classified as not popular.
We found that neo-builder demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers 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
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.