React, Vue and MDX
Components when you want them, JavaScript only where you need it.

vagejs is a static site generator that lets you build pages with React and Vue components and write content in MDX, then turns all of it into plain HTML when it builds your site. Visitors get no JavaScript unless you mark a React component interactive, and then only on the pages that use it.

npm create vagejs@latest my-site

Read the component docsAdd an interactive component

What you can build with components

Components are a nice way to build a site: write a pricing card once, use it on ten pages. The usual cost is JavaScript that every visitor downloads, even for parts of the page that never change. We keep the components and drop that cost.

  • Layouts as React or Vue components

    Write src/layouts/default.tsx or default.vue. A React layout gets the same data as a TypeScript one: the page, the site, the list of pages and your menus. Visitors get plain HTML and no JavaScript.

  • MDX pages

    MDX is Markdown that can use React components. Write src/pages/pricing.mdx and import any component from src/components/. It becomes plain HTML too, with no JavaScript.

  • Interactive React islands

    Add client:load, client:visible or client:idle to a React component and it runs in the browser. JavaScript goes only to the pages that use one.

Islands only where you ask

An island is one interactive part on an otherwise static page. It's rendered to HTML first, so visitors see the component right away and the page works while its JavaScript loads.

import Calculator from "../components/Calculator.tsx";

<Calculator client:load rate={4.5} />
Directive Starts
client:load as soon as the page loads
client:visible when it scrolls into view
client:idle when the browser has nothing else to do

With client:visible, visitors who never scroll that far never download the component.

MDX is checked like Markdown

MDX pages and component layouts get the same treatment as Markdown pages: titles, descriptions, sitemap entries, structured data, and vage check for broken links, hidden links and links to websites you haven't approved.

---
title: Pricing
description: Plans and prices.
---
import PlanCard from "../components/PlanCard.tsx";

# Pricing

<PlanCard name="Team" price="$20 a month" />

One difference: an MDX page is code, like a layout. It runs when the site is built, so vagejs can't clean it up the way it cleans HTML in Markdown pages. Keep MDX for content you'd trust in a layout.

Who React, Vue and MDX in vagejs are for

  • Teams that already think in React

    Reuse the components and habits you have, without turning a content site into an app.

  • Sites that need one or two interactive parts

    A price calculator, a filter or a short quiz, on a site that's otherwise static.

  • Anyone moving from a component framework

    Keep your layouts as components, and gain built-in checks and SEO files along the way.

What it costs

Sites that don't use components install nothing extra. Add React, Vue or MDX when you need them; if one is missing, the build tells you the exact command to install it.

An island does cost JavaScript. vage audit counts it on every page, including React itself (about 215 KB), which is over the default 100 KB budget. So adding one is a decision you make, not an accident. For many jobs, plain HTML does the same: a <details> element opens and closes, and a form can send without any script.

terminal
npm install react react-dom                  # React layouts
npm install --save-dev @mdx-js/mdx           # plus React, for MDX pages
npm install vue && npm install --save-dev @vitejs/plugin-vue   # Vue layouts

The limits, for now

Here's what doesn't work yet, so you can plan around it.

  • Interactive components are React only. Vue components work in layouts, as HTML.
  • Interactive components take plain data (text, numbers, lists) and can't contain other interactive components.
  • CSS imported inside components isn't collected. Put your styles in public/ and link them from the layout.

If you need islands in Vue or Svelte, or a site that's mostly interactive, see how vagejs compares with other tools.

More on React, Vue and MDX in vagejs

React support arrived in version 0.10 for layouts and MDX pages, and in 0.11 for interactive components.

Questions about React, Vue and MDX

Do I need to install React to use vagejs?

No. A site without components doesn't need React, Vue or MDX at all. Install each one when you start using it. If a page or layout needs a package that's missing, the build stops and prints the exact install command.

Why doesn't useState or onClick do anything in my component?

Only components marked with client:load, client:visible or client:idle run in the browser. Everything else is turned into HTML once, when the site is built, so state, effects and click handlers do nothing there. Mark the component interactive if it needs them.

How do I style my components?

Put your CSS in public/ and link it from your layout. CSS inside components, such as a Vue <style> block or import "./card.css", isn't added to the site.

Can I edit MDX pages in the browser editor?

Not yet. The editor that npm run dev opens lists .md pages only, so edit .mdx pages in your code editor.

Start with one command.
You'll have a site running in a minute.

npm create vagejs@latest my-site

Read the docsUse it with your AI assistant