The simple web framework and site generator you could have built yourself.
But since you didn’t, take Mastro as a starting point. It fills in the few missing pieces that aren’t built into modern browsers and JavaScript runtimes: a file-based router, and a handful of composable functions to return standard Response objects. Static site generation and on-demand rendering of HTML or JSON – it all works exactly the same in Mastro. Not compromising on developer experience, Mastro feels like a framework – but actually it’s just a tiny library.
- No bloat: written in just ~700 lines of TypeScript, Mastro is distilled to the essence.
- No client-side JavaScript (until you add some): create MPA websites that load blazingly fast.
- No bundler (until you add one): your code arrives in the browser exactly how you wrote it.
- No magic: use normal
<img>and<a>tags referencing HTTP-first assets. - No VC-money: no eventual enshitification – selling a service is not what we’re interested in.
- No update treadmill: we use web standards instead of relying on complex dependencies.
- No lock-in: swap out calls to the Mastro library later on. Or fork it – it’s only ~700 lines after all.
Try online with GitHub Install with Deno, Node.js or Bun
routes/index.server.ts
import { readMarkdownFiles } from "@mastrojs/markdown";
import { html, htmlToResponse } from "@mastrojs/mastro";
import { Layout } from "../components/Layout.ts";
export const GET = async (req: Request) => {
const posts = await readMarkdownFiles("data/posts/*.md");
return htmlToResponse(
Layout({
title: "Hello world",
children: posts.map((post) => html`
<p>${post.meta.title}</p>
`)
})
);
}
components/Layout.ts
import { html, type Html } from "@mastrojs/mastro";
interface Props {
title: string;
children: Html;
}
export const Layout = (props: Props) =>
html`
<!DOCTYPE html>
<html lang="en">
<head>
<title>${props.title}</title>
</head>
<body>
<h1>${props.title}</h1>
${props.children}
</body>
</html>
`;
Want to see more? Have a look at some examples, or the source of this website.
Easy for beginners
With Mastro, there is very little to learn – except for the web standards HTML, CSS, and JavaScript.
No installation needed
The popular VS Code editor also runs in the browser: put your first website live without installing anything on your computer.
Learn the fundamentals
Start with HTML and CSS. Then build a blog, and a to-do list app with JavaScript. Finally, run a server with a REST API.
Experienced developers – do you want off the frontend treadmill?
I’ve seen things you people wouldn’t believe. Megabytes of JavaScript on fire in the browser. I watched towers of complex abstractions collapse upon themselves. All those codebases will be lost in time, like tears in rain. Time to let them die.
There are various way to run Mastro. If you’re unsure which runtime to pick, we recommend Deno. For Node.js, pnpm is recommended, although npm and yarn also work.
Fast for everyone
Websites built with Mastro load fast
Performance
Accessibility
SEO
and build fast. For 500 markdown files:
| Mastro | 0.5s | 🏁 |
| Eleventy | 0.7s | |
| Astro | 2.2s | |
| Next.js | 16.3s |
Reactive Mastro – interactivity simplified
When you need client-side interactivity, add Reactive Mastro – a tiny reactive GUI library for MPAs.
Get started Why Reactive Mastro?
Join the community
It’s still early days. But we’re looking to build an inclusive community, where people of all kinds of backgrounds and experience levels feel welcome and safe. A place to ask questions and learn new things, where people help each other out.
Do you have a question, need help, or want to talk about future plans?
Something not working as expected or confusing? We consider that a bug.
Stay in touch
This is the end of the page. Yet it may be the beginning of your journey with Mastro.