Software development

Tech Pick of the Week: jsstana

This week's tech pick is a small JavaScript library, made for a very specific purpose by yours truly: jsstana. The homepage states “Find code inside your code! Pattern matching for Mozilla Parser AST, produced e.g. by esprima.” This might need a bit of explanation. I hope that the following examples will tell the story best.

Pattern matching

Consider you have to check whether a piece of text contains exactly three exclamation marks. There are many ways to tackle a problem even as simple as this one.

int has3exclmarks(const char *str, int len) {
    int count = 0;
    int len4 = len - 4;

    int i = 0;
    for (; i < len4 && count <= 3; i += 4) {
        uint32_t j = *((uint32_t *) (str + i));
        count += (j & (0xff)) == '!';
        count += (j & (0xff) << 8) == '!' << 8;
        count += (j & (0xff) << 16) == '!' << 16;
        count += (j & (0xff) << 24) == '!' << 24;

    for (; i < len; i++) {
        count += str[i] == '!';

    return count == 3;
hasThreeExclamationMarks = (3==) . length . filter ('!'==)
sub has3exclmarks {
    @_[0] =~ /^[^!]*![^!]*![^!]*![^!]*$/;

The first example is written in an


way. It's probably

very fast

(though I didn't check if it's really faster than a more trivial for loop, C compilers can work magic nowadays). On the other hand it's also very explicit about


it finds the answer.



example, the second one is very terse, and yet not obfuscated. There we combine even more primitive functions to get our job done. You can argue whether it's still


, or if it is already close to the executed definition,



The last example is by no means close to obfuscated. However, the regular expression shows exactly what we are searching for: three exclamation marks surrounded by anything else. That is very



But wait, what if the requirement changes? Say, now we still need to check whether a piece of text contains three exclamation marks but only if two of them are next to each other,

“like in this sentence! ni!!”

. Updating the above examples is left as an exercise for the reader.

Searching for pieces of code

Sometimes, actually pretty often when refactoring, you have to find a particular piece of code. With trivial needles like

new Errorgrep

is probably sufficient, assuming your code style is consistent and there is only ever one space between




(of course you could use

grep -E 'new\s+Error'

, couldn’t you?)

From time to time, you might want to find more complicated patterns, for example

the return of the sum of two expressions

, like

return (a*b) + c;

. Perhaps if you are writing rules for


, or trying to do some static analysis for the quality assurance of your JavaScript codebase by other means. With plain grep it will be painful (and you cannot really use it with eslint). Luckily there are JavaScript parsers, like




, which parse JavaScript source code into an Abstract Syntax Tree (AST). On the other hand it's more complicated to work with an AST, but on the other it's very precise.

Traversing and searching for patterns inside an AST without any helpers is very verbose:

function isReturnOfSum(node) {
    return node.type === "ReturnStatement" &&
        node.argument.type === "BinaryExpression" &&
        node.argument.operator === "+";

With more complex patterns it's very easy to “blow up” the code. Of course you should use helpers, or some kind of a library to help you.


goes further and provides a way to write patterns for matching within an AST.

var isReturnOfSum = jsstana.match("(return (+ ?lhs ?rhs))");

About jsstana

jsstana is a very young project, still already quite powerful. It can match everything we needed to match in our current project and a bit more. Fortunately it's extensible, so you can add more


as you like, without having to go through me.

Actually, you can try out jsstana on

its homepage

. Try to hover over matches on the right, or change different patterns at the bottom.

Or you can install

the npm package

, and use the


tool bundled with it. Nowadays I use it daily in project work, it's an easy substitute for plain grep, just two additional characters in the name.

Why lispy s-expressions?

This is the most frequent question asked about jsstana. I'm not trying to trick everyone into using ClojureScript. It just felt natural to use s-expressions for this need. And it took a quarter of an hour to write the parser and get to the fun part.

You could use

css selectors

, as you could for any tree structure. Or you could use JavaScript syntax itself. But both approaches are limiting, e.g. how to match returns with anything but the sum? With lispy s-expressions it's easy:

var isReturnOfNotSum = jsstana.match("(return (not (+ ? ?)))");

However, you can try out


, which is a relatively new project as well. Maybe it will include s-expression support by


. Maybe I'll borrow ideas from it. Time will tell.

I would like to hear feedback about jsstana. If you have any question, ideas or bug reports, please tell me, via