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 🙏

© 2025 – Pkg Stats / Ryan Hefner

side-effects-safe

v0.0.1

Published

If an expression's value is unused, can it be dropped?

Downloads

6

Readme

side-effects-safe

Provides lists of side-effects free functions and a helper to check if an abstract syntax tree expression node can be dropped if its value is not used.

Statically deciding if a piece of code changes program state is not trivial – Rice's theorem suggests that the problem is in general undecidable. However, side-effects safety (with false negatives) may suffice for optimization purposes.

Pure function lists

Three lists of functions are provided:

  • pureFuncs

    Calls to functions from this list should be safe to drop if the return value is not used (unless you do some nasty overriding).

  • pureFuncsWithUnusualException

    These functions might throw a (commonly unhandled) exception in rare circumstances. However, it should be "almost correct" to consider them pure (for the purpose of optimizing a web application). For instance, isFinite() and isNaN() may throw a TypeError if given a Symbol. 1

  • pureFuncsWithTypicalException

    Functions that do not have side-effects, but do throw exceptions that are commonly handled. An example is JSON.parse() throwing SyntaxError for malformed JSON.

Usage with Uglify

Pass one of the provided lists as the pure_funcs compressor option:

export PURE_FUNCS=`nodejs -p "require('side-effects-safe').pureFuncs"`
uglifyjs -c pure_funcs="$PURE_FUNCS" bundle.js

Usage through Webpack

The same within a webpack.config.js:

const pureFuncs = require('side-effects-safe').pureFuncs;
const webpack = require('webpack');

module.exports = {
    ...
    plugins: [
        new webpack.optimize.UglifyJsPlugin({compress: {pure_funcs: pureFuncs}})
    ]
};

AST expression tester

Babylon 6

A single pure(node, opts) function meant to be used by Babel transforms is currently available. The function checks if an AST expression node could be dropped if we knew that its value is not going to be used:

import * as t from 'babel-types';
import {pureBabylon as pure} from 'side-effects-safe';

pure(t.binaryExpression('*', t.identifier('a'), t.identifier('b')));  // true
pure(t.updateExpression('++', t.identifier('a')));  // false
Options

You may pass a regular expression matching accessor chains that can be assumed pure:

let ex = t.memberExpression(t.identifier('a'), t.identifier('b'));  // a.b
pure(ex);  // false
pure(ex, {pureMembers: /^a\.b$/});  // true

Similarly for callee expressions:

let ex = t.callExpression(t.identifier('f'), []);  // f()
pure(ex);  // false
pure(ex, {pureCallees: /^f$/});  // true

Regexes are matched against a string with dots, irrespective of the property style used in code (for example a[3].b['c'] is normalized to a.3.b.c and a[b] never matches).

Example

Here's a sketch of a transform to remove no-op expression statements:

import {pureBabylon as pure} from 'side-effects-safe';

export default () => ({
    visitor: {
        ExpressionStatement(path) {
            if (pure(path.node.expression)) {
                path.remove();
            }
        }
    }
});

This is implemented in babel-remove-pure-exps. Take a look at babel-remove-props for another usage example.

Installation

npm install side-effects-safe

The pure function lists were produced by skimming a draft of the ES7 standard from February 2016. If you note something inaccurate or outdated please open an issue.