Skip to main content
  _____ _      _____ __  __ _____ _______ ____  _  __
 / ____| |    |_   _|  \/  |_   _|__   __|___ \| |/ /
| (___ | |      | | | \  / | | |    | |    __) | ' /
 \___ \| |      | | | |\/| | | |    | |   |__ <|  <
 ____) | |____ _| |_| |  | |_| |_   | |   ___) | . \
|_____/|______|_____|_|  |_|_____|  |_|  |____/|_|\_\

Welcome to SlimIt3k

SlimIt3k is a Python 3-only fork of SlimIt, a JavaScript minifier written in Python. This fork was created because the original SlimIt was not updated on PyPI and no longer works with modern Python versions due to use of use_2to3, which was removed in setuptools 58.0.0.

SlimIt3k compiles JavaScript into more compact code so that it downloads and runs faster.

SlimIt3k also provides a library that includes a JavaScript parser, lexer, pretty printer and a tree visitor.

Current maintainer: Antti Haapala <antti.haapala@interjektio.fi>

https://slimit.readthedocs.io/

Installation

$ pip install slimit3k

Or the bleeding edge version from the git master branch:

$ pip install git+https://github.com/tetframework/slimit3k.git#egg=slimit3k

Let’s minify some code

From the command line:

$ slimit -h
Usage: slimit [options] [input file]

If no input file is provided STDIN is used by default.
Minified JavaScript code is printed to STDOUT.

Options:
  -h, --help            show this help message and exit
  -m, --mangle          mangle names
  -t, --mangle-toplevel
                        mangle top level scope (defaults to False)

$ cat test.js
var foo = function( obj ) {
        for ( var name in obj ) {
                return false;
        }
        return true;
};
$
$ slimit --mangle < test.js
var foo=function(a){for(var b in a)return false;return true;};

Or using library API:

>>> from slimit import minify
>>> text = """
... var foo = function( obj ) {
...         for ( var name in obj ) {
...                 return false;
...         }
...         return true;
... };
... """
>>> print minify(text, mangle=True, mangle_toplevel=True)
var a=function(a){for(var b in a)return false;return true;};

Iterate over, modify a JavaScript AST and pretty print it

>>> from slimit.parser import Parser
>>> from slimit.visitors import nodevisitor
>>> from slimit import ast
>>>
>>> parser = Parser()
>>> tree = parser.parse('for(var i=0; i<10; i++) {var x=5+i;}')
>>> for node in nodevisitor.visit(tree):
...     if isinstance(node, ast.Identifier) and node.value == 'i':
...         node.value = 'hello'
...
>>> print tree.to_ecma() # print awesome javascript :)
for (var hello = 0; hello < 10; hello++) {
  var x = 5 + hello;
}
>>>

Writing custom node visitor

>>> from slimit.parser import Parser
>>> from slimit.visitors.nodevisitor import ASTVisitor
>>>
>>> text = """
... var x = {
...     "key1": "value1",
...     "key2": "value2"
... };
... """
>>>
>>> class MyVisitor(ASTVisitor):
...     def visit_Object(self, node):
...         """Visit object literal."""
...         for prop in node:
...             left, right = prop.left, prop.right
...             print 'Property key=%s, value=%s' % (left.value, right.value)
...             # visit all children in turn
...             self.visit(prop)
...
>>>
>>> parser = Parser()
>>> tree = parser.parse(text)
>>> visitor = MyVisitor()
>>> visitor.visit(tree)
Property key="key1", value="value1"
Property key="key2", value="value2"

Using lexer in your project

>>> from slimit.lexer import Lexer
>>> lexer = Lexer()
>>> lexer.input('a = 1;')
>>> for token in lexer:
...     print token
...
LexToken(ID,'a',1,0)
LexToken(EQ,'=',1,2)
LexToken(NUMBER,'1',1,4)
LexToken(SEMI,';',1,5)

You can get one token at a time using token method:

>>> lexer.input('a = 1;')
>>> while True:
...     token = lexer.token()
...     if not token:
...         break
...     print token
...
LexToken(ID,'a',1,0)
LexToken(EQ,'=',1,2)
LexToken(NUMBER,'1',1,4)
LexToken(SEMI,';',1,5)

LexToken instance has different attributes:

>>> lexer.input('a = 1;')
>>> token = lexer.token()
>>> token.type, token.value, token.lineno, token.lexpos
('ID', 'a', 1, 0)

Benchmarks

SAM - JQuery size after minification in bytes (the smaller number the better)

Original jQuery 1.6.1 (bytes)

SlimIt SAM

rJSmin SAM

jsmin SAM

234,995

94,290

134,215

134,819

Roadmap

  • when doing name mangling handle cases with ‘eval’ and ‘with’

  • foo[“bar”] ==> foo.bar

  • consecutive declarations: var a = 10; var b = 20; ==> var a=10,b=20;

  • reduce simple constant expressions if the result takes less space: 1 +2 * 3 ==> 7

  • IF statement optimizations

    1. if (foo) bar(); else baz(); ==> foo?bar():baz();

    2. if (!foo) bar(); else baz(); ==> foo?baz():bar();

    3. if (foo) bar(); ==> foo&&bar();

    4. if (!foo) bar(); ==> foo||bar();

    5. if (foo) return bar(); else return baz(); ==> return foo?bar():baz();

    6. if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}

  • remove unreachable code that follows a return, throw, break or continue statement, except function/variable declarations

  • parsing speed improvements

Acknowledgments

  • The lexer and parser are built with PLY

  • Several test cases and regexes from jslex

  • Some visitor ideas - pycparser

  • Many grammar rules are taken from rkelly

  • Name mangling and different optimization ideas - UglifyJS

  • ASI implementation was inspired by pyjsparser

License

The MIT License (MIT)

Change History

0.9.0 (2025-09-18)

  • slimit3k fork. Polyglot code that should work similarly in Python 2.6+ and 3 alike. Removed 2to3 code. A new release by new name.

0.8.1 (2013-03-26)

0.8.0 (2013-03-23)

0.7.4 (2012-06-5)

0.7.3 (2012-05-21)

0.7.2 (2012-05-17)

0.7.1 (2012-05-10)

0.7 (2012-04-16)

0.6.2 (2012-04-07)

0.6.1 (2012-03-15)

0.6 (2012-02-04)

0.5.5 (2011-10-05)

0.5.4 (2011-10-01)

0.5.3 (2011-06-29)

0.5.2 (2011-06-14)

0.5.1 (2011-06-06)

0.5 (2011-06-06)

  • Added name mangling

0.4 (2011-05-12)

  • Minify more by removing block braces { }

  • More tests

0.3.2 (2011-05-09)

  • More hacks to use pre-generated lex and yacc tables when called from the command line

0.3.1 (2011-05-09)

  • Use pre-generated lex and yacc tables when called from the command line

0.3 (2011-05-09)

  • Added minifier

0.2 (2011-05-07)

  • Added a JavaScript parser

  • Added pretty printer

  • Added node visitor

0.1 (2011-05-02)

  • Initial public version. It contains only a JavaScript lexer

Metadata

Release files for slimit3k 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for slimit3k 0.9.0
File Size Uploaded Provenance Actions
slimit3k-0.9.0.tar.gz 69.5 kB Without provenance Details for slimit3k-0.9.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for slimit3k 0.9.0
File Interpreter ABI Platform Actions
slimit3k-0.9.0-py3-none-any.whl Python 3 none any Details for slimit3k-0.9.0-py3-none-any.whl

Total release size: 151.8 kB

Release files / slimit3k-0.9.0.tar.gz

Download URL slimit3k-0.9.0.tar.gz
Size 69.5 kB
Tags Source
SHA-256 checksum
How to use checksums
037a705f5097c112e545fbcd184a3b968d2ebb4c0cb90aa31fce305e28d2a28d
BLAKE2b-256 checksum
How to use checksums
867931ed57483ab94a99acaa8c9921e5648a16b499d2845159d04ce4c51be22f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / slimit3k-0.9.0-py3-none-any.whl

Download URL slimit3k-0.9.0-py3-none-any.whl
Size 82.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cd9a615cdf777859e0e5250e8483a492b9e8bc301a8cb8729c4075a7dcf167de
BLAKE2b-256 checksum
How to use checksums
e7aca0ad00f63672d8e5452b58e1ce6f83932dd8f7ab72d26c10669a69499111
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Security for slimit3k 0.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page