Moon Logo

The minimal & fast library for functional user interfaces

Applications today are complex, built on top of frameworks that create arbitrary abstractions fundamentally based on mutability and imperative code.

They introduce concepts like reactivity or local state or algebraic effects, all in attempt to represent views as a function of state.

In reality, applications are much more sophisticated and require third-party libraries for any effects other than updating a view.

Moon is a novel approach to web applications based on pure functions. An application is a function that uses drivers, programs that provide an interface to the real world.

These functions take input from drivers and return output to drivers. Drivers can be responsible for things like views, state, audio, HTTP requests, routing, and timing events.

Applications run on the Moon, and drivers update the Earth.

Functional & Declarative

In Moon, web applications are treated as functions that take driver inputs and return driver outputs. Drivers handle the interface between the output of your application and the browser so that it can stay pure and declarative.

On the contrary, other popular frameworks claim to be "declarative" but only treat the view as a function of state. However, they treat other ideas such as local component state or effects as afterthoughts, requiring imperative and impure code.

Try it!

const increment = ({ data, view }) => {
    const dataNew = data + 1;

    return {
        data: dataNew,
        view: (<View data={dataNew}/>)
    };
};

const View = ({ data }) => (
    <button @click={increment}>{data}</button>
);

Moon.use({
    data: Moon.data.driver(0),
    view: Moon.view.driver("#root")
});

Moon.run(({ data, view }) => ({
    view: (<View data={data}/>)
}));

Tiny & Fast

Modern web frameworks often add a lot of weight to JavaScript bundles, resulting in slower web applications and load times. This effect is especially visible when using a slow internet connection.

Since Moon is so simple at its core, where it creates an abstraction to allow drivers to handle input and output, it only weighs 1kb minified and gzipped. On top of that, it is specifically optimized for JavaScript engines to perform fast virtual DOM diffing and DOM operations.

Sizes of popular frameworks relative to Moon. Performance of popular frameworks relative to Moon.

Intuitive & Consistent

Moon has a very minimal API surface, used solely for initializing a runtime that allows for functional applications inside the imperative browser environment. The view language was designed to mimic HTML, a language familiar to most web developers.

Other view languages often have variadic arguments that can have any type for creating view nodes. They create abstractions like directives or special template syntax for control flow.

Moon's view language is consistent, where every tag is a function call. Components are just functions that return more nodes, and they are compiled to function calls like every other node. Control flow is implemented with components as well. In essence, it is JavaScript with syntactic sugar for function calls.

// Moon View
const posts = (
    <for={post} of={posts}>
        <Box id="my-box">{post}</Box>
    </for>
);

// Compiled to JS
var m0, m1, m2, m3, m4;
const posts = (function() {
    if (m3 === undefined) {
        m3 = [];
        m4 = {};
    }
    m0 = [];
    m1 = function(post) {
        return Box({
            id: "my-box",
            children: [Moon.view.m("text", { "": post }, m3)]
        });
    };
    for (m2 = 0; m2 < posts.length; m2++) {
        m0.push(m1(posts[m2], m2));
    }
    return Moon.view.m("span", m4, m0);
})();

Jump into the guide to get started.