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

exfoliate

v0.0.8

Published

Function inliner for reducing code complexity

Readme

exfoliate - JavaScript Function Inliner

A comprehensive AST-based function inliner for reducing code complexity and flattening nested function calls.

Features

Smart Inlining Strategy

  • Single-use functions are inlined: Functions called exactly once are automatically inlined
  • Multi-use functions are preserved: Functions called multiple times remain as reusable methods
  • Predictable and reliable: Uses topological sorting to inline dependencies in the correct order

Complete Scope Management

  • Variable conflict resolution: Automatically renames variables that would conflict
  • Parameter substitution: Replaces function parameters with actual arguments
  • Shadowing prevention: Handles variable shadowing correctly

Early Return Handling

  • Semantic preservation: Correctly handles early returns using control flow flags
  • Nested returns: Properly transforms returns inside if statements and blocks
  • Control flow integrity: Ensures code after early returns doesn't execute

Example

Before:

export class D {
  constructor() {
    this._super_C_constructor();
    console.log('d');
  }
  _super_A_constructor() {
    console.log('a');
  }
  _super_B_constructor() {
    this._super_A_constructor();
    console.log('b');
  }
  _super_C_constructor() {
    this._super_B_constructor();
    console.log('c');
  }
}

After:

export class D {
  constructor() {
    console.log('a');
    console.log('b');
    console.log('c');
    console.log('d');
  }
}

Usage

import { inline } from './inliner.js';
import { readFileSync } from 'fs';

const code = readFileSync('./your-file.js', 'utf-8');
const inlinedCode = await inline(code);

console.log(inlinedCode);

How It Works

1. Call Graph Analysis

Analyzes which functions call which, and counts how many times each function is called.

2. Candidate Selection

Identifies functions called exactly once as candidates for inlining.

3. Topological Ordering

Sorts functions so that dependencies are inlined first (leaves to root).

4. AST Transformation

For each inlined function:

  • Clone the function body
  • Rename local variables to avoid conflicts
  • Substitute parameters with arguments
  • Handle return statements with control flow flags if needed
  • Replace the call site with the transformed body

5. Code Generation

Generates clean, formatted code using astring and prettier.

Advanced Features

Early Return Transformation

Original:

function validate(value) {
  if (value < 0) {
    return false;
  }
  if (value > 100) {
    return false;
  }
  return true;
}

Inlined:

let result$1;
let returned_result$1 = false;
if (!returned_result$1) {
  if (num < 0) {
    result$1 = false;
    returned_result$1 = true;
  }
}
if (!returned_result$1) {
  if (num > 100) {
    result$1 = false;
    returned_result$1 = true;
  }
}
if (!returned_result$1) {
  result$1 = true;
}

Variable Shadowing Resolution

Original:

function shadowTest() {
  const temp = 5;
  const result = helper(temp);
  return result;
}

function helper(x) {
  const temp = x + 10; // Shadows outer temp
  return temp;
}

Inlined:

function shadowTest() {
  const temp = 5;
  const temp$1 = temp + 10; // Renamed to avoid conflict
  const result = temp$1;
  return result;
}

Multi-use Function Preservation

// _reusable_log is called 3 times, so it's NOT inlined
_reusable_log(message) {
  console.log('[LOG]', message);
}

method1() {
  this._reusable_log('From method1');
  return 1;
}

method2() {
  this._reusable_log('From method2');
  return 2;
}

Test Results

From the test module:

  • Original code: 3,848 characters
  • Inlined code: 2,923 characters
  • Reduction: ~24%
  • Functions analyzed: 32
  • Inline candidates: 15
  • Functions inlined: 15
  • Preserved (multi-use): 2 (_reusable_log, _multiple_a)

Use Cases

  1. Flattening inheritance chains: Inline super constructor calls
  2. Removing helper abstraction overhead: Inline single-use helper methods
  3. Simplifying code flow: Make code more linear and easier to understand
  4. Improving AI collaboration: Reduce indirection for better AI code analysis

Architecture

  • ScopeTracker: Manages variable bindings and generates unique names
  • CallGraphAnalyzer: Builds call graph and counts function usage
  • SimpleVariableRenamer: Renames variables to avoid conflicts
  • ParameterSubstituter: Replaces parameter references with arguments
  • ReturnHandler: Transforms return statements for inlining
  • Inliner: Main orchestrator that coordinates the inlining process

Limitations

  • Recursive functions cannot be inlined (detected and rejected)
  • External function calls are not analyzed
  • Dynamic calls (e.g., via call, apply) are not tracked
  • Requires valid JavaScript that parses with acorn

Dependencies

  • acorn: JavaScript parser
  • astring: AST to code generator
  • prettier: Code formatter

License

MIT