Skip to content
Docs · 11 pages

Docs / Start here

Installation

One command, or a manual install when you want to own every line.

2 min readThis page as MarkdownSource on GitHub

One command

npx astro add moonarc

This installs @moonarc/core and the moonarc integration entry, adds the integration to astro.config.mjs, and that is the whole setup. The integration does three small things you would otherwise do by hand:

  1. Injects @moonarc/core/styles/base.css on every page: the theme-aware tokens (--ma-ease-out, --ma-edge, …) every component reads.
  2. Adds a 92-byte inline script to <head> that sets data-ma-js on <html> before first paint, and again after every <ClientRouter /> navigation. Entrance effects hide content only behind that attribute, so a page whose JavaScript never runs still shows everything.
  3. Optionally adds the package to vite.ssr.noExternal. It is off by default because Astro 5, 6 and 7 do not need it.

Then import what you use:

---
import Reveal from '@moonarc/core/Reveal';
---
<Reveal><h2>Hello</h2></Reveal>

Each component is its own subpath export, so importing one never pulls the stylesheet or script of another.

Manual install

If you prefer no integration, install the components package:

npm install @moonarc/core

Then do by hand what the integration does:

astro.config.mjs
// nothing needed
src/layouts/Base.astro
---
import '@moonarc/core/styles/base.css';
import { gateScript } from '@moonarc/core';
---
<head>
  <style is:inline>@layer theme, base, components, utilities;</style>
  <script is:inline set:html={gateScript} />
</head>

The <style> line fixes the order of the cascade layers before any stylesheet loads. base.css opens with the same statement, and the integration imports it ahead of everything else on every page. Without the integration, a component’s CSS can load first. components is then the first layer declared and ranks lowest, so a reset in base (Tailwind’s preflight is one) beats every component rule. Keep the statement first in <head>.

gateScript is the text the integration injects. It sets data-ma-js again after every navigation. The older one-line gate set it once, and lost it for the rest of the visit at the first navigation from a page that loads no Moonarc script.

Without the gate script

Scroll reveals are visible from the start. Nothing breaks, and nothing animates in.

Copy the source with the shadcn CLI

Every component page has the full source and a shadcn-compatible registry command:

npx shadcn@latest add https://moonarc.dev/r/reveal.json

The registry item brings the shared runtime with it. Components that compose another (SplitText uses Reveal) declare that as a registry dependency.

The CLI needs a components.json, which an Astro project does not have, and the copied files import one another through the @/* alias. Setup has both files, written so that package.json stays as it is. Files land in src/components/moonarc/ and src/lib/moonarc/, and the base stylesheet in src/styles/moonarc.css.

Import that stylesheet once, and give the layout the same two lines in <head> as a manual install: the layer statement first, then the gate. @moonarc/core is not installed this way, so put the gate’s text from the integration inside the <script is:inline> instead of gateScript.

Requirements

  • Astro 5, 6 or 7. Verified on every release against all three, in static and server output.
  • No Tailwind required. Components use scoped, layered CSS and custom properties. The Tailwind token layer is opt-in (see motion tokens).
  • The Node version your Astro major requires: 22.12 or later for Astro 6 and 7; 18.20.8, 20.3 or a later 20, or 22 and later for Astro 5.