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

spintax

v1.1.2

Published

Combinatorial string generator using spintax syntax

Readme

Spintax

A combinatorial string generation library that creates all possible combinations from templates with variable elements.

Installation

npm install spintax
import parse from "spintax";

Web Usage

You can also import the library directly in your HTML file using a CDN:

<script type="module">
  import parse from "https://cdn.jsdelivr.net/npm/[email protected]/src/index.mjs";
</script>

Note that https://ga.jspm.io/npm:[email protected]/src/index.mjs is also available.

Key Features

  • String pattern parsing: Create string variations using intuitive pattern syntax
  • Combinatorial expansion: Generate all possible combinations of variable elements
  • Memory-efficient: Uses JavaScript iterators for lazy evaluation
  • Multiple variable types: Choose from predefined options or numerical ranges

Overview

Spintax is a JavaScript library for generating all possible combinations of template strings with variable elements. It uses a simple, intuitive pattern syntax ({...}) to define variables within templates.

Basic Usage

import parse from "spintax";

// Basic usage with choices
const variations = parse("Hello, {world|friend|universe}!");

// Iterate through all combinations
for (const variation of variations) {
  console.log(variation);
}
// Output:
// Hello, world!
// Hello, friend!
// Hello, universe!

// With numerical ranges
const counts = parse("Count: {1,5}");
// Generates: "Count: 1", "Count: 2", "Count: 3", "Count: 4", "Count: 5"

// Multiple variables
const products = parse("{Product|Service} #{1,3} ({Standard|Premium})");
// Generates all combinations: "Product #1 (Standard)", "Product #1 (Premium)", etc.

// Back references
const associations = parse(
  "The {blue|straw|rasp}berries taste like {$0}berries)"
);
// Generates all combinations with back references: "The blueberries taste like blueberries", "The strawberries taste like strawberries", "The raspberries taste like raspberries", etc.

Pattern Syntax

Choices

Define choices with the pipe (|) separator:

parse("Color: {red|green|blue}");
// Generates: "Color: red", "Color: green", "Color: blue"

Ranges

Define ranges with comma-separated numbers:

parse("Value: {1,5}");
// Generates: "Value: 1", "Value: 2", "Value: 3", "Value: 4", "Value: 5"

// With step value
parse("Value: {0,10,2}");
// Generates: "Value: 0", "Value: 2", "Value: 4", "Value: 6", "Value: 8", "Value: 10"

Pattern Combinations

Multiple patterns in a template will generate all possible combinations:

parse("{small|large} {box|circle} in {red|blue}");
// Generates 8 combinations of size, shape and color

Whitespace Handling

  • In range patterns (containing numbers and commas), all whitespace is ignored
    • {1,5} is the same as { 1, 5 }
  • In choices patterns (with | separators), whitespace is preserved as part of the option
    • {option1|option2} is different from {option1 |option2}
    • In the second case, the first option is "option1 " (with a trailing space)

Advanced Examples

URL Generation

parse("https://example.com/{products|users}/{1,5}");
// Generates:
// https://example.com/products/1
// https://example.com/products/2
// ...
// https://example.com/users/5

API Testing

parse("/api/v{1,3}/{users|items}/{1,100,10}");
// Generates:
// /api/v1/users/1
// /api/v1/users/11
// ...
// /api/v3/items/91

Configuration Generation

parse(
  '{"timeout": {1000,5000,1000}, "retries": {1,3}, "mode": "{strict|lenient}"}'
);
// Generates valid JSON strings with all combinations of parameters

Iteration Order

When multiple patterns are in a template, combinations are generated by iterating through the rightmost pattern first (inner loop), then the next one to the left, and so on:

parse("The color is {red|green|blue}. The letter is {A|B|C}");

// Produces:
// The color is red. The letter is A
// The color is red. The letter is B
// The color is red. The letter is C
// The color is green. The letter is A
// The color is green. The letter is B
// The color is green. The letter is C
// The color is blue. The letter is A
// The color is blue. The letter is B
// The color is blue. The letter is C

Performance Considerations

Combinatorial Explosion

Be cautious when creating templates with many variable parts, as the number of combinations can grow exponentially:

  • 3 variables with 4 options each: 4³ = 64 combinations
  • 5 variables with 4 options each: 4⁵ = 1,024 combinations
  • 10 variables with 4 options each: 4¹⁰ = 1,048,576 combinations

Chunking for Large Result Sets

When dealing with extremely large sets of combinations, consider processing them in chunks:

const template = parse("..."); // Large combination space
const iterator = template[Symbol.iterator]();
const chunkSize = 1000;

function processNextChunk() {
  let count = 0;
  let result;

  while (count < chunkSize && !(result = iterator.next()).done) {
    process(result.value);
    count++;
  }

  if (!result.done) {
    // Schedule next chunk processing
    setTimeout(processNextChunk, 0);
  }
}

processNextChunk();

Best Practices

  1. Limit Pattern Count: Keep the number of variable patterns reasonable to avoid combinatorial explosion
  2. Use Meaningful Options: Create patterns that produce meaningful variations
  3. Process Lazily: Process combinations lazily when dealing with large result sets

Advanced API

While parse is the primary function exported from the library, there are additional utility functions available for more advanced use cases:

Supporting Utilities

import { compile, range, count } from "spintax";

compile Tagged Template Function

For programmatic template creation with JavaScript expressions:

compile`Hello ${["world", "universe"]}!`;

range(start, end, step = 1, includeEnd = true)

Creates a numerical range generator:

range(1, 5); // 1, 2, 3, 4, 5
range(0, 10, 2); // 0, 2, 4, 6, 8, 10

count(template)

Counts the number of combinations a template would generate:

count("Hello!"); // 1
count("Hello {world|people|nurse}!"); // 3

choose(template)

Produces a function that yields specific combinations based on the indexs passed to it:

const gen = choose("Hello {world|nurse}!");
gen(0); // "Hello world!"
gen(1); // "Hello nurse!"

Omitting the index returns a random combination:

gen(); // "Hello world!" or "Hello nurse!"

Browser Compatibility

The library uses modern JavaScript features:

  • Template literals
  • Generator functions
  • Iterable protocol

Migrating from 0.0.x

If you are migrating from version 0.0.x to 1.0.0, please note that the API has changed significantly.

spintax.unspin to choose

  • The unspin function has been replaced with choose.

Old:

import spintax from "spintax";
const result = spintax.unspin("{Hello|Hi} John!");
console.log(result); // "Hello John!" or "Hi John"

Current:

import { choose } from "spintax";
const result = choose("{Hello|Hi} John!");
console.log(result()); // "Hello John!" or "Hi John"

spintax.countVariations to count

  • The countVariations function has been replaced with count.

Old:

import spintax from "spintax";
const count = spintax.countVariations("{Hello|Hi} John!");
console.log(count); // 2

Current:

import { count } from "spintax";
const count = count("{Hello|Hi} John!");
console.log(count); // 2

License

MIT