Discover the open source JavaScript libraries that power Mathigon. Combining functions for DOM manipulation, animations, events handling, UI elements and mathematics, they make web development for modern browsers fun and easy.

Explore Source on GitHub is home to four different JavaScript libraries designed for high performance and fast development:

While core.js and fermat.js can run in any environment, boost.js and slate.js require a browser.


All libraries are written entirely in ES6. They are split into a few different modules which export public functions and classes. To use any one, you simply need to import it. 

import { tabulate, average } from 'arrays'
import Matrix from 'matrix'

IDEs like WebStorm, we recommend marking the src/ folder in every library as resource root, so that dependencies are correctly resolved. If you want to create a single concatenated file for browsers, you can use tools like Webpack, Browserify or jspm. At Mathigon we use rollup.js which runs tree shaking to remove all unused functions and classes. This significantly reduces the file size of the resulting bundle. You can see a Grunt-based example on GitHub.

For improved performance, very few of the functions perform argument checks or throw errors. If a function is called with incorrect arguments, the behaviour is undefined can could range from silent typecasting to unexpected errors. Where needed, the caller is responsible for checking that parameter match the types defined in this documentation.

Arrays contains various different functions for efficient array creation and manipulation.

tabulate(Math.random, 5);
  // [0.7068, 0.9314, 0.6050, 0.9042, 0.2278]

flatten(tabulate((x, y) => '' + x + y, 3, 3));
  // ['00', '01', '02', '10', '11', '12', '20', '21', '22']

map((x, y, z) => x + y + z, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
  // [12, 15, 18]

  // [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

  // [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]

  //[[4,5,6], [4,6,5], [5,4,6], [5,6,4], [6,4,5], [6,5,4]]

Expressions and Mathematics

Fermat.js is able to parse complex mathematical expressions, including arbitrary functions, arrays and strings. When evaluating, you can pass in custom variables and functions.

let expr = Expression.parse('1 * (2 + x) - 4! + average([1, 2, x^2]) - (100 / 2)%');
expr.evaluate({ x: 10, average });


boost.js contains a powerful wrapper class for DOM elements. You can use $ and $$ to select one or more dom elements on the current page, and $N and $$N to create new elements.

let $parent = $('.foo');
let $child = $N('div', { class: '.bar', html: 'Hello' }, $parent);

$child.on('click', function() { ... });


Everything in is based on events. Many classes inherit from Evented which supports basic .on, .one, .off and .trigger methods.

In addition to standard browser events, boost.js also supports a number of special events. The click event is overwritten to happen on mouseup or touchend to avoid delays on mobile devices. The scroll, scrollStart and scrollEnd events are fired for mouse and touch scrolling using requestAnimationFrame. Mathigon also simulates cross-platform pointer events.

$element.on('click', function() { console.log('click'); });
$element.on('scroll', function({ top }) { console.log(top); });
$element.on('pointerStart', function(e) { console.log(; });


Boost.js contains a variety of element transitions, including .enter(), .exit(), and effects like .pulsate(). You can also define generic element animations which use CSS transition to animate any css properties. In particular, you can animate to and from height: auto and width: auto.

$el.exit('fade', 300, 100);  // duration 300ms, delay 100ms

  { css: 'background', from: '#C00', to: '#0C0', duration: 500, timing: 'linear', delay: 200 },
  { css: 'width', to: '200px' }

animate() is a wrapper for requestAnimationFrame that can be used to call a function at every step during an animation of fixed length, or indefinitely.

animate(function(prog, time) {
  $el.css(left, prog * 200 + 'px');
  $el.text(time + 's');
}, 500);

Web Components

To use a web component in slate.js, you simply need to import the relevant module in your JavaScript entry point, even though you'll rarely used the imported class. The browser will automatically convert all corresponding tags, e.g. <x-dropdown></x-dropdown>.

Many components contain a Less stylesheet, which you similarly need to import in your styles entry point. Others contain a jade template file which similarly needs to be compiled and added at the top of your html.

<!-- This is not a standard feature: you need to manually compile and insert templates. -->
<link rel="import" href="slate.js/dropdown/template.js">
import XDropdown from 'dropdown'
let $el = $('x-dropdown')
@import 'slate.js/src/dropdown/styles.less'

Instead, you can also define your own web components using `customElement()`.

import { $, customElement, $body } from 'elements';

export default customElement('x-foo', {

  created: function($el) { ... },
  attached: function($el) { ... },
  detached: function($el) { ... },

  template: '<div>foo: <content></content></div>'

Boost's custom elements don't use Shadow DOM, but you can use the Shadow DOM <content select=""> syntax in template strings. Tools like webpack allow you to write styles and templates in external files and insert them as strings in the compiled JavaScript file when building your application.



To contribute code, please fork our GitHub repository and send us a pull request. If you find bugs or mistakes in Mathigon JS, please email us with details on how to reproduce them.