Concepts
Here are some ideas explained.
Server-side Virtual DOM
By running the application on the server, you have complete control over the environment in which it runs.
You can communicate with your database directly from your app without having to implement an API inbetween.
The only state that gets exposed to clients is the data you include in the DOM.
Callbacks are regular POST-request with an identifier that maps to a component and a callback name.
Deploy globally
You can deploy Mayu to data centers around the world within minutes with very little configuration.
Letβs say youβre making an app for finding lunch restaurants around the world. You would have traffic 24/7, but you would have more users in regions closer to lunch time.
With Mayu, you would just increase the number of instances in those regions. New instances start within seconds.

Resumability
Before a server shuts down, it serializes the state and sends it to the browser, so that it can send it to another server and resume the state.
Mayu restores the state of components automatically. Users shouldnβt notice anything most of the time.
However, if the user loses their connection for too long, the session will expire on the server, and they will have to start a new session.
If youβre making an app for users on shaky internet connections, then Mayu is probably not the right tool.
Efficiency
The browser runtime loads the chunk that makes the connection to the server first, and then loads remaining chunks asynchronously. This way, the browser can many times connect to the even stream before the page has even rendered.
Mayu only updates the parts that have changed on a site. When you navigate to a different page, only the difference between the current page and the new page will be rendered and sent to the browser.
Asset filenames are based on their content hash so that they can be cached very easily, and browsers will only have to download stylesheets and images etc that have changed since their last visit.
Asset files are usually small and compressed when possible. Everything loads in parallel over HTTP/2 so bundling CSS-files together would actually only make things worse.
Metrics
Mayu exposes a Prometheus endpoint with metrics that you can use to visualize how your app is performing.

Easy to use
Mayu is written in Ruby which is famous for being user friendly and has been used on the web for a very long time.
Mayu uses Haml in a similar way that React uses JSX, which results in clean and simple markup in your components.
:ruby
Button = import("/components/Form/Button")
def initialize =
@count = $initial_count || 0
def handle_reset =
@count = $initial_count || 0
def handle_increment =
@count += 1
def handle_decrement =
@count -= 1
.counter
%p Count: #{@count}
%Button(onclick=handle_decrement) Decrement
%Button(onclick=handle_reset) Reset
%Button(onclick=handle_increment) Increment
:css
.counter {
display: flex;
flex-wrap: wrap;
gap: .5em;
align-items: center;
}
p {
margin: 0 auto 0 0;
font-variant-numeric: tabular-nums;
}
Count: 0
Mayu was designed with hot reloading in mind from the start. This is a popular feature in many JavaScript build tools like Webpack and Vite, and it makes web development fun because of the fast feedback loop.
When a component keeps the same module identity and key, Mayu preserves its serializable local state while replacing the component class. The replacement receives current props, and its mount lifecycle is restarted.
Hot reloading makes development super fast.
info: Mayu::Build::UpdateLogger β Update #43 completed β changed files:β ~ components/Form/Button.hamlβ reloaded:β ~ app:/components/Form/Button.hamlβ reevaluated:β * app:/pages/docs/concepts/HamlExample.hamlβ * app:/pages/docs/concepts/+page.hamlβ * virtual:/router.rbβ assets:β + /components_Form_Button_haml_inline_0_css.8da258a9ecfe67ec.cssβ + /components_Form_Button_haml_inline_0_css.d2def4628ee5d299.css.mapβ - /components_Form_Button_haml_inline_0_css.89c275abb6e4c961.cssβ - /components_Form_Button_haml_inline_0_css.56f3c77102879a44.css.mapBuilt for the future
Mayu uses the latest browser features and does not support older browsers.