npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@astx/compiler

v3.1.0

Published

Compiler library for a tiny JS AST based binary file format

Readme

@astx/compiler

Compiles JavaScript source code to the ASTX binary format. Part of the ASTX monorepo.


Installation

npm install @astx/compiler

API

compile(code, skipTransformers?, opts?)

Parses and optimises JavaScript source code, returns a CompiledProgram.

import { compile } from "@astx/compiler";

const program = compile(`
  const result = 2 ** 10;
  console.log(result);
`);

Options (CompileOptions):

| Option | Type | Default | Description | |---|---|---|---| | sourceMap | boolean | false | Attach [line, col] info to every bytecode slot | | verbose | boolean | false | Print transformer activity to the logger | | logger | CompileLogger | console | Custom logger – implement { log, warn } to redirect output |

skipTransformers is an optional array of transformer names to disable for this compilation.

Controlling log output:

By default all [ASTX-Compiler] output is suppressed (verbose: false). Enable it or route it to your own logging system:

// Enable built-in console output
const program = compile(source, [], { verbose: true });

// Redirect to a custom logger (e.g. pino, winston, a test spy)
const program = compile(source, [], {
  verbose: true,
  logger: {
    log: (...args) => myLogger.debug(args.join(" ")),
    warn: (...args) => myLogger.warn(args.join(" ")),
  },
});

.warn() is always forwarded regardless of verbose so transformer errors are never silently swallowed.


toBuffer(program, opts?): Promise<Uint8Array>

Serialises a CompiledProgram to the compressed ASTX binary format.

import { compile, toBuffer } from "@astx/compiler";

const program = compile(source);
const bytes = await toBuffer(program);

Options (ToBufferOptions):

| Option | Type | Default | Description | |---|---|---|---| | codec | AstxCodec | Node.js built-in zstd | Custom compress/decompress implementation | | level | number | 22 | Zstd compression level (1–22) | | dict | Uint8Array | — | Pre-trained Zstd dictionary (requires custom codec) |


saveToFile(program, filename, opts?): Promise<void>

Convenience wrapper: serialises and writes the binary to disk. Node.js only.

import { compile, saveToFile } from "@astx/compiler";

const program = compile(source);
await saveToFile(program, "output.astx");

Browser support

All APIs are browser-compatible. The default codec uses node:zlib via a dynamic import — in a browser you must supply a custom AstxCodec:

import { compress, decompress } from "@mongodb-js/zstd"; // WASM-backed
import { compile, toBuffer } from "@astx/compiler";

const program = compile(source);
const bytes = await toBuffer(program, {
  codec: { compress, decompress },
});

AST Transformers

The compiler runs these optimisation passes automatically before encoding, in the order shown:

| # | Transformer | What it does | |---|---|---| | 1 | TreeShaking | Removes unused top-level function, class, and side-effect-free variable declarations | | 2 | InlineConstantVariables | Replaces every reference to a const primitive literal with the literal itself, then removes the declaration | | 3 | ConstantFolding | Evaluates constant expressions at compile time (2 + 35) | | 4 | DeadCodeElimination | Removes unreachable code after return/throw/break/continue | | 5 | LogicalSimplification | Simplifies !!x, x === true, x === false, etc. | | 6 | PowToMultiply | Replaces x ** 2 / x ** 3 with equivalent multiplications | | 7 | ForEachToForLoop | Converts .forEach(cb) to a for loop | | 8 | HoistArrayLength | Caches arr.length outside the loop condition | | 9 | ForOfToIndexed | Converts for…of over arrays to index-based for loops | | 10 | InlineArrowToFunction | Converts inline arrow callbacks to function expressions where safe | | 11 | AssignedArrowToFunction | Converts assigned arrow functions to regular function expressions (scope-aware) | | 12 | UnchainMapToLoop | Converts .map(fn) chains to for loops | | 13 | UnchainFilterToLoop | Converts .filter(fn) chains to for loops | | 14 | UnchainReduceToLoop | Converts .reduce(fn) chains to for loops | | 15 | FusionLoop | Merges consecutive loops over the same array | | 16 | RedundantReturnElimination | Removes trailing return; / return void 0; from the end of function bodies | | 17 | ConsecutiveVarMerging | Merges consecutive const/let/var declarations of the same kind into one (const a = 1; const b = 2;const a = 1, b = 2;) | | 18 | RestoreExportedNames | Preserves original names for exported bindings after renaming passes |

InlineConstantVariables (pass 2) feeds directly into ConstantFolding (pass 3): after literals are inlined, the folding pass collapses any resulting constant expressions in the same compilation run.

To disable individual transformers:

const program = compile(source, ["FusionLoop", "PowToMultiply"]);

The "keep-functional" preset keeps only the lightweight, purely-syntactic passes (passes 1–6, 16–18) and skips the loop-rewriting transformers:

const program = compile(source, "keep-functional");

Benchmarks

The package ships Vitest benchmarks for compile() and toBuffer() against small, medium, and large JS fixtures.

pnpm bench

Example results (Apple M-series):

| Benchmark | ops/sec | |---|---| | compile() – small program | ~5 400 | | compile() – medium program | ~1 900 | | compile() – large program | ~330 | | toBuffer() – small → binary | ~47 000 | | toBuffer() – large → binary | ~20 500 |


Known limitations

  • AOT side-effects – Transformers may change observable behaviour if the input code relies on subtle JS semantics (e.g. exact prototype chains, arguments binding). Review the transformer list above for caveats.
  • Dynamic import() and top-level await – Partially supported; behaviour depends on the runtime execution mode.

License

GPL-3.0 — see LICENSE.