[{"url":"/blog/","title":"Blog","description":"Writing from the Mira team on building fast, well designed content sites, the web platform, and how Mira works inside.","headings":[{"id":"blog-empty-title","text":"No posts yet."}],"text":"Blog Writing on building fast, well designed content sites, the web platform, and how Mira works inside. RSS feed No posts yet. Every release so far is in the changelog. Follow the RSS feed to get the first post when it lands. Read the changelog RSS feed"},{"url":"/changelog/v0-1-2/","title":"The README on npm, and releases you can verify","description":"The npm page now carries the full README with MCP and deploy guides, and each npm release is verified against its source and approved with 2FA.","headings":[{"id":"documentation","text":"Documentation"},{"id":"security","text":"Security"},{"id":"maintenance","text":"Maintenance"}],"text":"Changelog 0.1.2 2026-10-08 The README on npm, and releases you can verify The npm page now carries the full README with MCP and deploy guides, and each npm release is verified against its source and approved with 2FA. Documentation The npm page for @miraframework/mira shows the full README. It now explains how to connect mira mcp to an MCP client, with the three tools it offers, and how to deploy to each supported host. Links and images in the npm README point at this release’s tag on GitHub, so the page always matches the version you install. Security npm packages are released with trusted publishing. npm checks each release against the repository’s release workflow through GitHub’s OIDC token, and no npm token is stored anywhere. Every version is staged first and goes live only after a maintainer approves it on npmjs.com with two-factor authentication. Each package carries a provenance statement that links it to the exact commit and workflow run that built it. Maintenance The release and CI workflows use the current versions of the GitHub actions they depend on, each pinned to a commit SHA. Install this version npm i @miraframework/mira@0.1.2 Binaries and checksums Source at v0.1.2 All releases"},{"url":"/changelog/v0-1-1/","title":"Mira on npm","description":"Mira installs from npm. One package gives you the mira command, and npm fetches the native binary for your platform.","headings":[{"id":"added","text":"Added"},{"id":"notes","text":"Notes"}],"text":"Changelog 0.1.1 2026-10-07 Mira on npm Mira installs from npm. One package gives you the mira command, and npm fetches the native binary for your platform. Added @miraframework/mira , the mira command for npm. It runs the native binary for your machine and passes arguments, output, and exit codes through unchanged. Six platform packages, from @miraframework/mira-linux-x64 to @miraframework/mira-win32-arm64 . npm installs only the one that matches your system. create-mira . Run npm create mira@latest my-site to get the starter site with dev and build scripts in its package.json . Notes 0.1.0 was released on GitHub only. 0.1.1 is the first version on npm. Install this version npm i @miraframework/mira@0.1.1 Binaries and checksums Source at v0.1.1 All releases"},{"url":"/changelog/v0-1-0/","title":"First public release","description":"Mira is open source. A static site framework for content sites, with native page transitions, typed content, and output that people and agents can both read.","headings":[{"id":"build","text":"Build"},{"id":"motion","text":"Motion"},{"id":"media-and-search","text":"Media and search"},{"id":"security","text":"Security"},{"id":"agents","text":"Agents"},{"id":"hosting-and-migration","text":"Hosting and migration"}],"text":"Changelog 0.1.0 2026-10-07 First public release Mira is open source. A static site framework for content sites, with native page transitions, typed content, and output that people and agents can both read. Build mira new , mira dev , and mira build . --json reports results and errors as JSON. Routes, layouts, and templates in .mira and Markdown files, with escaped output by default. Content collections with typed frontmatter schemas, checked on every build with the file and line of each error. Size budgets per page. A page over budget fails the build. Motion Cross-document View Transitions with shared elements through mira-morph , route pair overrides, direction awareness, and reduced motion support. Links prefetched or prerendered with Speculation Rules. Media and search <mira-frame> reserves space for each image, encodes AVIF, and shows an 8×8 placeholder until the image loads. A search index written at build time, loaded only by pages that use search. Security A strict Content Security Policy with a hash for every inline script and style. Security headers written for every supported host. Agents A Markdown version of every page, llms.txt , a sitemap, RSS feeds, and JSON-LD. mira mcp serves the site’s pages to any MCP client. Hosting and migration Native config for Vercel, Netlify, Cloudflare Pages, GitHub Pages, Firebase, Render, Azure Static Web Apps, Docker, Deno Deploy, and S3 with CloudFront, plus redirects in each host’s format. mira migrate imports Next.js, Astro, Hugo, Jekyll, Docusaurus, Gatsby, Eleventy, and VitePress sites and writes a redirect for every U"},{"url":"/changelog/","title":"Changelog","description":"Every Mira release, newest first, with what changed, how to install it, and a link to its binaries on GitHub.","headings":[],"text":"Changelog Every Mira release, newest first. Each one links to its full notes and to its binaries on GitHub. RSS feed Releases on GitHub CHANGELOG.md 0.1.2 2026-10-08 0.1.2 The README on npm, and releases you can verify The npm page now carries the full README with MCP and deploy guides, and each npm release is verified against its source and approved with 2FA. Documentation Security Maintenance npm i @miraframework/mira@0.1.2 Full notes GitHub release 0.1.1 2026-10-07 0.1.1 Mira on npm Mira installs from npm. One package gives you the mira command, and npm fetches the native binary for your platform. Added Notes npm i @miraframework/mira@0.1.1 Full notes GitHub release 0.1.0 2026-10-07 0.1.0 First public release Mira is open source. A static site framework for content sites, with native page transitions, typed content, and output that people and agents can both read. Build Motion Media and search Security Agents Hosting and migration Binaries on GitHub only Full notes GitHub release"},{"url":"/docs/introduction/","title":"Introduction","description":"What Mira is, what kind of sites it builds, and what you get from a build.","headings":[{"id":"what-a-build-gives-you","text":"What a build gives you"},{"id":"how-a-build-works","text":"How a build works"}],"text":"All docs Introduction What Mira is, what kind of sites it builds, and what you get from a build. Mira builds content sites: documentation, blogs, portfolios, product and editorial pages. You write Markdown and .mira templates; mira build writes plain HTML files you can host anywhere. This site is built with it. What a build gives you Pages that work without JavaScript. Each page is an index.html with its CSS inlined. The optional runtime that handles transitions and prefetching is about 1 KB gzipped. Page transitions. Navigation animates with the browser’s View Transitions. Add mira-morph to an element and it travels to its match on the next page. Typed content. Frontmatter is checked against a schema on every build, and errors name the file and line. Images that never shift the layout. <mira-frame> reserves each image’s space, encodes AVIF, and shows a small placeholder until it loads. Search. An index written at build time, loaded only on pages with a search box. Output agents can read. A Markdown copy of every page, llms.txt , and mira mcp to serve the site to MCP clients. Security headers and a strict content security policy , built from hashes of each page’s own code. Config for your host. Vercel, Netlify, Cloudflare Pages, GitHub Pages, and six more, written on every build. Checks before deploy. Broken links, missing assets, and pages over their size budget fail the build. How a build works Source Folder Becomes Pages and layouts routes/ , layouts/ HTML pages with inlined CSS Content content/ , data/ Pages, feeds, search, and Markdown copies Config mira.config.j"},{"url":"/docs/installation/","title":"Installation","description":"Install Mira from npm, download a prebuilt binary, or build it from source, then check that it works.","headings":[{"id":"start-a-new-site","text":"Start a new site"},{"id":"add-mira-to-an-existing-project","text":"Add Mira to an existing project"},{"id":"download-a-binary","text":"Download a binary"},{"id":"build-from-source","text":"Build from source"},{"id":"check-the-install","text":"Check the install"},{"id":"verify-a-release","text":"Verify a release"}],"text":"All docs Installation Install Mira from npm, download a prebuilt binary, or build it from source, then check that it works. Mira is one native binary named mira , built for Linux (x64 and arm64), macOS (Apple silicon and Intel), and Windows (x64 and arm64). Start a new site npm create mira@latest my-site This creates my-site/ from the starter template and adds a package.json with dev and build scripts and Mira as a dev dependency. Then: cd my-site npm install npm run dev Node.js 18 or later is needed to install. The mira binary itself runs without Node. Add Mira to an existing project npm install -- save-dev @miraframework/mira npm installs the binary for your platform alongside a small launcher, so npx mira and mira inside package scripts both work. Download a binary Each release on GitHub has an archive per platform and a SHA256SUMS file. Unpack the archive and put mira on your PATH . Build from source With a Rust toolchain installed: cargo install -- git https://github.com/buildwithmira/mira mira Check the install npx mira -- version mira --help lists every command, and mira build --help shows the options for one. Verify a release Every npm package is built and published by the repository’s release workflow and carries a provenance statement linking it to that build. To check the packages in a project: npm audit signatures"},{"url":"/docs/quick-start/","title":"Quick start","description":"Create a site, run it locally with live reload, add a post, and build it for production in five commands.","headings":[{"id":"create-a-site","text":"Create a site"},{"id":"run-it-locally","text":"Run it locally"},{"id":"add-a-post","text":"Add a post"},{"id":"build","text":"Build"},{"id":"deploy","text":"Deploy"}],"text":"All docs Quick start Create a site, run it locally with live reload, add a post, and build it for production in five commands. Create a site npm create mira@latest my-site cd my-site npm install The starter has a home page, an about page, a blog with two posts, a layout, mira.config.json , and an AGENTS.md that tells coding agents how the project works. Run it locally npm run dev The site is served at http://localhost:4321 and rebuilds when you save. If a build fails, an overlay shows the file, the line, and a fix; save a correction and it clears. Open Writing , then a post. The title morphs from the list into the post, and the back button plays it in reverse. Add a post Create content/posts/hello.md : --- title: Hello description: My first post on my new Mira site, written in Markdown. date: 2026-10-08 --- Written in Markdown, rendered at build time. It appears at /posts/hello/ and at the top of /posts/ . Every post is checked against the schema in mira.config.json , so a missing title or a malformed date fails with the exact line. See Content collections . Build npm run build The site lands in dist/ as static files. The summary lists each page’s gzipped size against its budget, and the files written for agents and hosts. Deploy Name your host in mira.config.json and the build writes its config file: { \" hosts \" : { \" vercel \" : { } } } Then deploy dist/ . See Deploying for all ten supported hosts."},{"url":"/docs/project-structure/","title":"Project structure","description":"The folders and files of a Mira project and what each one does.","headings":[{"id":"folders","text":"Folders"},{"id":"public-files","text":"Public files"},{"id":"generated-folders","text":"Generated folders"}],"text":"All docs Project structure The folders and files of a Mira project and what each one does. A Mira project is a folder with a config file and a few conventional directories. Only routes/ is required. my-site/ ├── mira.config.json Site, theme, transitions, schemas, and checks ├── AGENTS.md Conventions for coding agents ├── routes/ Pages; every file is a URL │ ├── index.mira │ ├── about.md │ └── posts/ │ ├── index.mira │ └── [slug].mira One page per entry in content/posts/ ├── layouts/ │ └── default.mira Wraps every page unless a page opts out ├── content/ │ └── posts/ A collection: Markdown files with frontmatter ├── data/ JSON or YAML available to every template ├── public/ Copied to the output as is └── dist/ Build output; safe to delete Folders Folder Purpose Docs routes/ .md and .mira files that become pages Routing layouts/ .mira components that wrap pages Layouts content/ One folder per collection of Markdown entries Content collections data/ Structured data such as navigation Data files public/ Static files served from the site root below Public files Everything in public/ is copied to the output with the same path: public/favicon.svg is served at /favicon.svg . If public/favicon.svg exists, every page links it as the icon. A file in public/ wins over a generated file with the same name. Put your own robots.txt there and Mira skips its generated one, with a warning so the choice stays visible. Generated folders dist/ holds the production build. Mira writes a .mira-ou"},{"url":"/docs/routing/","title":"Routing","description":"How files in routes/ become URLs, including dynamic routes and the 404 page.","headings":[{"id":"file-to-url","text":"File to URL"},{"id":"markdown-pages","text":"Markdown pages"},{"id":"component-pages","text":"Component pages"},{"id":"dynamic-routes","text":"Dynamic routes"},{"id":"the-404-page","text":"The 404 page"},{"id":"page-titles","text":"Page titles"},{"id":"drafts","text":"Drafts"}],"text":"All docs Routing How files in routes/ become URLs, including dynamic routes and the 404 page. Every .md or .mira file in routes/ is a page. Its path in the folder is its URL. File to URL File URL Output file routes/index.mira / index.html routes/about.md /about/ about/index.html routes/docs/index.mira /docs/ docs/index.html routes/docs/setup.md /docs/setup/ docs/setup/index.html routes/posts/[slug].mira /posts/<slug>/ one file per entry routes/404.md /404.html 404.html URLs end with a slash, and each page is written as index.html in its own folder, which every static host serves without configuration. Two files that produce the same URL fail the build and name both files. Markdown pages A .md route is rendered as Markdown and wrapped in <article class=\"prose\"> . Frontmatter sets its title, description, layout, and transition: --- title: About description: Who we are. --- # About Text in Markdown. Component pages A .mira route is a component with a template and optional styles. Use one when a page needs layout, loops, or data. See Templates . Dynamic routes A file named in brackets, such as routes/posts/[slug].mira , renders once for every entry of a collection. The collection is the folder’s name, so routes/posts/[slug].mira reads content/posts/ . Set collection: in the route’s frontmatter to use another: --- collection: articles --- < template > < article > < h1 > {{ entry.title }} </ h1 > < slot /> </ article > </ template > Inside a dynamic route, entry holds the entry’s frontmatter, slug , and url , and <slot /> renders its Markdown. Dynamic routes must be .mira f"},{"url":"/docs/templates/","title":"Templates","description":"The .mira component format and its template syntax.","headings":[{"id":"output","text":"Output"},{"id":"conditions","text":"Conditions"},{"id":"loops","text":"Loops"},{"id":"slots","text":"Slots"},{"id":"literal-braces","text":"Literal braces"},{"id":"what-templates-can-read","text":"What templates can read"},{"id":"styles","text":"Styles"},{"id":"built-in-elements","text":"Built in elements"},{"id":"errors","text":"Errors"}],"text":"All docs Templates The .mira component format and its template syntax. A .mira file is a single file component: optional frontmatter, a <template> block, and an optional <style> block. It compiles to HTML and CSS with no runtime. --- title: Writing --- < template > < h1 > {{ page.title }} </ h1 > < ol > {#each collections.posts as post} < li > < a href = \" {{ post.url }} \" > {{ post.title }} </ a > </ li > {/each} </ ol > </ template > < style > ol { list-style : none ; padding : 0 ; } </ style > If a file has no <template> block, the whole body is the template. Output Write a value with double braces. Output is HTML escaped, so < , > , & , and quotes are always safe: < h1 > {{ page.title }} </ h1 > < a href = \" {{ post.url }} \" > Read </ a > To write raw HTML, mark it unsafe . Every use is reported as a warning at build time so it stays a deliberate choice: {{ unsafe page.trusted_html }} Values are read by dotted paths. Arrays take numeric indexes and a length : {{ collections.posts.0.title }} {{ collections.posts.length }} posts A missing path renders nothing. Strings print as is, numbers and booleans print as text, and lists or objects print as JSON. Conditions {#if post.description} < p > {{ post.description }} </ p > {:else} < p > No summary. </ p > {/if} {#if !path} negates. A value is false when it is missing, null , false , 0 , an empty string, or an empty list. Loops {#each collections.posts as post} < h2 > {{ post.title }} </ h2 > {/each} Loop variables shadow outer names inside the loop. Slots <slot /> marks where wrapped content goes. In a layout it is the page;"},{"url":"/docs/layouts/","title":"Layouts","description":"Wrap pages in shared chrome, choose a layout per page, or opt out.","headings":[{"id":"choosing-a-layout","text":"Choosing a layout"},{"id":"the-document-shell","text":"The document shell"},{"id":"give-the-page-a-main-landmark","text":"Give the page a main landmark"},{"id":"navigation-state","text":"Navigation state"}],"text":"All docs Layouts Wrap pages in shared chrome, choose a layout per page, or opt out. A layout is a .mira file in layouts/ that wraps pages. Its <slot /> is where the page goes. < template > < header > < a href = \" / \" > {{ site.title }} </ a > < nav > < a href = \" / \" mira-nav > Home </ a > < a href = \" /posts/ \" mira-nav > Writing </ a > </ nav > </ header > < main id = \" main \" > < slot /> </ main > </ template > < style > body { max-width : 46 rem ; margin -inline : auto ; } </ style > Choosing a layout Frontmatter Result none layouts/default.mira if it exists, otherwise no layout layout: docs layouts/docs.mira ; the build fails if it does not exist layout: false No layout; the page renders on its own A layout sees the same site , page , entry , collections , and data as the page it wraps. The document shell Layouts render inside <body> . Mira writes everything around it: the doctype, <html lang> , the content security policy, title, description, canonical URL, Open Graph tags, the inlined CSS, the runtime, and the prefetch rules. You never write a <head> . Give the page a main landmark Put the page in <main id=\"main\"> . Mira then holds the first paint until main is parsed, so shared elements exist when an incoming transition takes its snapshot, and moves keyboard focus to the main heading after navigation. A skip link to #main is good practice: < a class = \" skip \" href = \" #main \" > Skip to content </ a > Navigation state Add mira-nav to navigation links. The compiler sets aria-current=\"page\" on the link whose href matches the page, or whose href is a section the page i"},{"url":"/docs/collections/","title":"Content collections","description":"Group Markdown entries, type their frontmatter, and sort, link, and list them.","headings":[{"id":"entries","text":"Entries"},{"id":"listing-a-collection","text":"Listing a collection"},{"id":"rendering-entries-as-pages","text":"Rendering entries as pages"},{"id":"order","text":"Order"},{"id":"schemas","text":"Schemas"},{"id":"drafts","text":"Drafts"},{"id":"feeds","text":"Feeds"}],"text":"All docs Content collections Group Markdown entries, type their frontmatter, and sort, link, and list them. A collection is a folder in content/ . Each Markdown file in it, including in subfolders, is an entry with frontmatter and a body. content/ └── posts/ ├── motion-is-navigation.md └── ship-less.md Entries --- title: Ship less description: Every byte sent to a browser must justify itself. date: 2026-09-21 --- The body is Markdown. Each entry gets: Field Value slug The slug frontmatter, or the file name without .md url Set when a dynamic route renders the collection, otherwise null reading_time Minutes at 230 words per minute, at least 1 toc Second and third level headings: level , id , text prev , next The neighboring entries’ title and url , in collection order Slugs cannot contain spaces, slashes, ? , or # . Listing a collection Every template can read collections.<name> : {#each collections.posts as post} < a href = \" {{ post.url }} \" > {{ post.title }} </ a > {/each} Rendering entries as pages A dynamic route renders one page per entry. See Routing . Order Entries with a numeric order come first, lowest first. The rest follow newest first by date , then alphabetically by slug. These docs use order ; a blog uses date . Schemas Declare the fields a collection’s frontmatter must have in mira.config.json : { \" collections \" : { \" posts \" : { \" fields \" : { \" title \" : \" string \" , \" description \" : \" string? \" , \" date \" : \" date \" , \" tags \" : \" string[]? \" } } } } Type Accepts string Text number Numbers boolean true or false date A date like 2026"},{"url":"/docs/markdown/","title":"Markdown","description":"The Markdown Mira renders at build time, from tables to callouts and highlighted code.","headings":[{"id":"supported-syntax","text":"Supported syntax"},{"id":"headings","text":"Headings"},{"id":"code","text":"Code"},{"id":"callouts","text":"Callouts"},{"id":"footnotes","text":"Footnotes"},{"id":"prose-styles","text":"Prose styles"}],"text":"All docs Markdown The Markdown Mira renders at build time, from tables to callouts and highlighted code. Mira renders Markdown at build time, so none of it costs the reader any JavaScript. It follows CommonMark with the GitHub extensions. Supported syntax Tables, strikethrough, task lists, and footnotes Heading ids with {#custom-id} after a heading Smart punctuation: straight quotes become curly, -- becomes an en dash, --- an em dash Raw HTML, passed through as written Headings Every heading gets an id from its text, so ## Shared elements links as #shared-elements . Repeated headings get -1 , -2 , and so on. Second and third level headings are collected into the page’s toc , which this site shows as On this page . Code Fenced code blocks are highlighted at build time into classes the theme colors: ``` rust fn main() { println!(\"Hello from Mira\"); } ``` fn main ( ) { println! ( \" Hello from Mira \" ) ; } The language label shows in the block’s corner. Mira understands the common languages, including Rust, JavaScript, HTML, CSS, JSON, YAML, Markdown, Python, Go, and shell. A few names map to the closest grammar: mira , svelte , and vue highlight as HTML, and ts , tsx , and jsx as JavaScript. Unknown languages render as plain, escaped text. Callouts Start a quote with a marker to make a callout: > [!NOTE] > Useful information. Useful information the reader should notice. A better way to do something. Something the reader needs to know. Something that needs attention right away. The risks of an action. Footnotes Mira writes footnotes 1 with links back to the text. 1 Like thi"},{"url":"/docs/data-files/","title":"Data files","description":"Keep navigation and other structured data in JSON or YAML and read it from any template.","headings":[{"id":"example-docs-navigation","text":"Example: docs navigation"},{"id":"errors","text":"Errors"}],"text":"All docs Data files Keep navigation and other structured data in JSON or YAML and read it from any template. Files in data/ are loaded at build time and exposed to every template as data.<name> , where the name is the file name without its extension. Dashes become underscores, so docs-nav.json is data.docs_nav . File Template name data/docs.json data.docs data/team.yaml data.team data/docs-nav.yml data.docs_nav Example: docs navigation This site’s sidebar is one JSON file: [ { \" title \" : \" Getting started \" , \" items \" : [ { \" title \" : \" Introduction \" , \" url \" : \" /docs/introduction/ \" } , { \" title \" : \" Installation \" , \" url \" : \" /docs/installation/ \" } ] } ] And one loop in the docs route: {#each data.docs as section} < p > {{ section.title }} </ p > < ul > {#each section.items as item} < li > < a href = \" {{ item.url }} \" mira-nav > {{ item.title }} </ a > </ li > {/each} </ ul > {/each} Every URL in the file is checked at build time like any other link, so a renamed page cannot leave a dead sidebar entry. Errors Invalid JSON or YAML fails the build with the file and line."},{"url":"/docs/page-transitions/","title":"Page transitions","description":"Native, cross document transitions with route pairs, direction, and accessible defaults.","headings":[{"id":"how-it-works","text":"How it works"},{"id":"choosing-a-transition","text":"Choosing a transition"},{"id":"route-pairs","text":"Route pairs"},{"id":"built-in-transitions","text":"Built in transitions"},{"id":"direction","text":"Direction"},{"id":"custom-transitions","text":"Custom transitions"},{"id":"timing","text":"Timing"},{"id":"accessibility","text":"Accessibility"},{"id":"prefetching","text":"Prefetching"}],"text":"All docs Page transitions Native, cross document transitions with route pairs, direction, and accessible defaults. Moving between pages animates by default. Mira uses the browser’s cross document view transitions, so each page stays plain HTML and the animation costs no framework code. How it works Every page opts in to view transitions. When the next page arrives, the runtime, about 1 KB gzipped, picks a transition name and a direction and hands them to the browser, which animates from a snapshot of the old page to the new one. Browsers without cross document view transitions navigate normally. Nothing breaks; the motion is an enhancement. Choosing a transition Mira picks the first match: A route pair in config that matches the navigation The destination page’s transition frontmatter transitions.default in config, which is fade unless you change it { \" transitions \" : { \" default \" : \" fade \" , \" pairs \" : { \" /posts/ -> /posts/* \" : \" slide-up \" } } } --- title: Changelog transition: slide --- Route pairs A pair key is \"<from> -> <to>\" . Each side is an exact path such as /posts/ , or a prefix ending in * such as /posts/* , which matches any path under it but not the prefix itself. Navigating a pair in the opposite direction plays the transition backwards. With the pair above, opening a post slides up, and returning to the list, by link or by the back button, slides down. Built in transitions Name Forward Back fade Crossfade Crossfade slide-up New page rises in Old page sinks out slide Pushes in from the right Pulls in from the left none No animation No animation Dire"},{"url":"/docs/shared-elements/","title":"Shared elements","description":"Make an element travel between pages with the mira-morph attribute.","headings":[{"id":"what-the-compiler-does","text":"What the compiler does"},{"id":"rules","text":"Rules"},{"id":"styling-the-motion","text":"Styling the motion"},{"id":"tips","text":"Tips"}],"text":"All docs Shared elements Make an element travel between pages with the mira-morph attribute. A shared element is the same thing shown on two pages, such as a post title on a list and on the post itself. Give both the same mira-morph name and it moves from one position to the other during the transition. <!-- routes/posts/index.mira --> {#each collections.posts as post} < a href = \" {{ post.url }} \" > < h2 mira-morph = \" title-{{ post.slug }} \" > {{ post.title }} </ h2 > </ a > {/each} <!-- routes/posts/[slug].mira --> < h1 mira-morph = \" title-{{ entry.slug }} \" > {{ entry.title }} </ h1 > On this site, each page’s heading carries a name like doc-routing , so a link with the same name morphs into it. What the compiler does mira-morph=\"title-ship-less\" becomes data-mira-morph=\"title-ship-less\" , and the page’s own stylesheet gets: [ data-mira-morph = \" title-ship-less \" ] { view- transition -name : title-ship-less ; view- transition -class : mira-morph ; } Names live in the stylesheet rather than in inline style attributes, so pages keep a strict content security policy. Rules Unique per page. A name used twice on one page makes the browser skip the whole transition, so Mira fails the build instead. Valid names. Characters other than letters, digits, - , and _ become - . A name starting with a digit gets an m- prefix. none , auto , root , and other CSS keywords are rejected. Stable elements. An element with the same name and position on both pages, such as a site header, holds still while the rest of the page changes. This site’s docs sidebar uses that to stay put. Sty"},{"url":"/docs/theming/","title":"Theming","description":"Pick light or dark, change colors, type, spacing, and motion from mira.config.json, and style pages without fighting the defaults.","headings":[{"id":"light-or-dark","text":"Light or dark"},{"id":"change-tokens","text":"Change tokens"},{"id":"tokens","text":"Tokens"},{"id":"your-css-wins","text":"Your CSS wins"}],"text":"All docs Theming Pick light or dark, change colors, type, spacing, and motion from mira.config.json, and style pages without fighting the defaults. Every Mira page starts with a theme written as CSS custom properties. Change any of them from config, or use them in your own CSS. Light or dark { \" scheme \" : \" dark \" } Value Result dark Dark theme, the default light Light theme system Follows the reader’s setting Color tokens use light-dark() , so the same names work in both themes. Change tokens Set values under theme . Nested keys join with dashes into the property name: { \" theme \" : { \" ink \" : \" #f4f1ea \" , \" radius \" : { \" md \" : \" 10px \" } , \" font \" : { \" display \" : \" Inter, system-ui, sans-serif \" } , \" motion \" : { \" morph \" : \" 640ms \" } } } That sets --ink , --radius-md , --font-display , and --motion-morph above the defaults. Values cannot contain { , } , ; , or < . Tokens Token Use --surface-0 , --surface-1 , --surface-2 Page ground, raised panels, and wells such as code blocks --ink , --ink-muted , --ink-faint Text, from primary to captions --line , --line-strong Dividers and control borders --focus Focus rings --font-text , --font-display , --font-mono Body, headings, and code --text-sm , --text-base , --text-lg Text sizes --display-sm to --display-xl Fluid heading sizes --space-1 , -2 , -3 , -4 , -6 , -8 , -12 , -16 , -24 Spacing: the step times 4px, so --space-6 is 24px --radius-sm , --radius-md , --radius-lg , --radius-xl Corner radii --motion-fast , --motion-control , --motion-morph Durations for crossfades, controls, and shared elements Your CSS wins M"},{"url":"/docs/components/","title":"Components","description":"The built in buttons, tabs, cards, code blocks, and search box, with their markup. Each page ships only the CSS it uses.","headings":[{"id":"button","text":"Button"},{"id":"tabs","text":"Tabs"},{"id":"card","text":"Card"},{"id":"code","text":"Code"},{"id":"search","text":"Search"}],"text":"All docs Components The built in buttons, tabs, cards, code blocks, and search box, with their markup. Each page ships only the CSS it uses. Components are plain HTML with a class. The compiler checks each page’s HTML and inlines CSS only for the components that page uses. Button < a class = \" mira-btn \" href = \" /start/ \" > Start building </ a > < a class = \" mira-btn \" data-variant = \" outline \" href = \" /docs/ \" > Read the docs </ a > < button class = \" mira-btn \" data-size = \" sm \" > Copy </ button > Solid , the default, is the main action on a surface. Outline is for secondary actions. data-size=\"sm\" makes a compact 32px button. Tabs Pill navigation. Add mira-nav to each link and the current page is marked with aria-current . < nav class = \" mira-tabs \" aria-label = \" Primary \" > < a href = \" / \" mira-nav > Home </ a > < a href = \" /docs/ \" mira-nav > Docs </ a > </ nav > Card < a class = \" mira-card \" href = \" /docs/routing/ \" > < h2 > Routing </ h2 > < p > How files become URLs. </ p > </ a > A link card lifts 2px on hover. Code Fenced code blocks in Markdown render with syntax highlighting. In a .mira template, use <mira-code lang=\"rust\"> . See Markdown . Search <mira-search> renders a search box over the site’s index. See Search ."},{"url":"/docs/fonts/","title":"Fonts","description":"Serve font files from your own site with preloading and swap, so pages make no requests to font services.","headings":[{"id":"why-self-host","text":"Why self host"}],"text":"All docs Fonts Serve font files from your own site with preloading and swap, so pages make no requests to font services. Put font files in public/ and list them in config. Mira writes the @font-face rules into each page’s CSS and preloads the faces you mark. { \" fonts \" : [ { \" family \" : \" Inter \" , \" src \" : \" /fonts/Inter.woff2 \" , \" weight \" : \" 100 900 \" , \" preload \" : true } , { \" family \" : \" JetBrains Mono \" , \" src \" : \" /fonts/JetBrainsMono.woff2 \" , \" weight \" : \" 100 800 \" } ] , \" theme \" : { \" font \" : { \" text \" : \" Inter, system-ui, sans-serif \" , \" display \" : \" Inter, system-ui, sans-serif \" , \" mono \" : \" \\\" JetBrains Mono \\\" , ui-monospace, monospace \" } } } The theme.font keys set the --font-text , --font-display , and --font-mono tokens, so the new families apply everywhere. See Theming . Key Default Meaning family required The family name used in CSS src required Path under public/ , starting with / weight 400 One weight, or a range such as 100 900 for variable fonts style normal normal or italic preload false Preload the file. Use it for one or two faces above the fold. Every face uses font-display: swap , so text shows at once in a fallback font and swaps when the file arrives. A missing file fails the build. Why self host A font from another origin is an extra connection before text can render, and a third party that sees every visit. Fonts from your own site stay inside the page’s content security policy, cache with the site, and send no data elsewhere."},{"url":"/docs/media/","title":"Media frames","description":"Put every image and video in a frame that reserves its space, loads from a mosaic, and ships as AVIF.","headings":[{"id":"images","text":"Images"},{"id":"markdown-images","text":"Markdown images"},{"id":"video","text":"Video"},{"id":"output","text":"Output"},{"id":"media-json","text":"media.json"},{"id":"the-rule-for-decoration","text":"The rule for decoration"}],"text":"All docs Media frames Put every image and video in a frame that reserves its space, loads from a mosaic, and ships as AVIF. Every image and video in Mira lives in a frame, and the frame is the only decoration. Each part of it does a job: Reserved space. The compiler writes the exact width and height, so the page never jumps. Pixel mosaic. An 8×8 mosaic of the image’s real colors paints first, then resolves into the photo in steps. It is the loading state, built from the logo’s pixel module. Corner handles. They appear only when the image opens full size, so they tell the reader it is clickable. Hairline border. It is the only line, and it doubles as the focus ring. Caption line. Mono text that holds the real caption and credit. Images < mira-frame src = \" ./pipeline.png \" alt = \" Build pipeline \" caption = \" Cold build, 1,000 pages \" credit = \" Mira \" zoom > </ mira-frame > In Markdown, keep the whole <mira-frame> tag on one line. Markdown only treats a line as HTML when the opening tag is complete on that line, so a tag split across lines renders as text. In .mira templates, any layout works. Attribute Meaning src The file. ./x.png is relative to the file that contains the frame, /x.png is under public/ , and @/x.png is under the project root alt Required. Describe the image, or use alt=\"\" when it is decoration caption Optional caption shown under the frame credit Optional credit, shown after the caption zoom The frame links to the original at full size and shows corner handles Frames take PNG, JPEG, GIF, WebP, AVIF, and SVG. A missing alt fails the build with the fil"},{"url":"/docs/performance/","title":"Performance","description":"What Mira does to make pages load first and stay small, and the budgets that keep them that way.","headings":[{"id":"what-a-page-contains","text":"What a page contains"},{"id":"component-css-on-demand","text":"Component CSS on demand"},{"id":"prefetching","text":"Prefetching"},{"id":"images","text":"Images"},{"id":"budgets","text":"Budgets"},{"id":"build-speed","text":"Build speed"}],"text":"All docs Performance What Mira does to make pages load first and stay small, and the budgets that keep them that way. Mira’s job is to send less. A content page is one HTML file with everything it needs to render inside it. What a page contains HTML rendered at build time. No component code runs in the browser and nothing hydrates. Inlined CSS. The base styles, the theme, the layout’s and page’s styles, and only the component CSS the page uses, in one <style> element. There is no stylesheet request to wait for. A runtime of about 1 KB. Gzipped, inline in the head. It sets the transition and its direction, moves focus after navigation, and prefetches in browsers without Speculation Rules. Prefetch rules. A small Speculation Rules block for the next page. Component CSS on demand Each component’s CSS is tagged with its class. While writing a page, the compiler checks the HTML and inlines only the blocks whose class appears, so a page without buttons carries no button CSS. Prefetching { \" prefetch \" : { \" eagerness \" : \" moderate \" , \" prerender \" : true } } Setting Effect eagerness: \"conservative\" Prefetch when a link is pressed eagerness: \"moderate\" Prefetch when a pointer rests on a link, the default eagerness: \"eager\" Prefetch as early as the browser allows prerender: true Also prerender on press, so the page is fully rendered before it is shown Only same origin links are fetched. Opt a link, or every link inside an element, out with data-mira-no-prefetch ; use it for links that change state or need a signed in session. Links with download are skipped. Browsers with"},{"url":"/docs/search/","title":"Search","description":"A build time index for every page and a search box that reads it.","headings":[{"id":"using-it","text":"Using it"},{"id":"ranking","text":"Ranking"},{"id":"the-index","text":"The index"},{"id":"styling","text":"Styling"}],"text":"All docs Search A build time index for every page and a search box that reads it. Every build writes a search index to /_mira/search.json . Add a search box with one element: < mira-search placeholder = \" Search docs \" > </ mira-search > The element’s script is a separate file that loads only on pages that use it, and the index is fetched the first time the box is focused. Pages without search pay nothing. Using it Press / anywhere on the page to focus the box. Results update as you type, best match first, with the matching words highlighted. Use the arrow keys to move through results and Escape to close them. When a term matches a section heading, the result links straight to that section. Ranking A page scores for each search term found in its title, then its section headings, then its description, then its text. Every term must match somewhere for a page to appear. The index The index is a JSON array with one object per page: { \" url \" : \" /docs/routing/ \" , \" title \" : \" Routing \" , \" description \" : \" How files in routes/ become URLs. \" , \" headings \" : [ { \" id \" : \" dynamic-routes \" , \" text \" : \" Dynamic routes \" } ] , \" text \" : \" Every .md or .mira file in routes/ is a page… \" } Text comes from the page’s <main> element, without navigation, scripts, or SVG, and is capped at 1,600 characters per page; titles and headings carry most of the weight. The 404 page is left out. The same file is a search API for agents: fetch it, filter it, and follow the canonical URLs. mira mcp exposes it as a search tool. See MCP server . Styling The box and its results use the d"},{"url":"/docs/seo/","title":"SEO and AI search","description":"Get pages found by search engines and cited by AI answer engines, and decide what each kind of crawler may do.","headings":[{"id":"on-every-page","text":"On every page"},{"id":"frontmatter","text":"Frontmatter"},{"id":"site-settings","text":"Site settings"},{"id":"crawler-policy","text":"Crawler policy"},{"id":"build-checks","text":"Build checks"},{"id":"for-ai-answer-engines","text":"For AI answer engines"}],"text":"All docs SEO and AI search Get pages found by search engines and cited by AI answer engines, and decide what each kind of crawler may do. Mira writes the metadata search engines and AI answer engines read, checks it on every build, and lets you choose separately what search, AI answers, and AI training may do with your pages. On every page From frontmatter and config, each page gets a title, description, canonical URL, Open Graph and Twitter card tags, and structured data: Page Structured data Home WebSite and Organization , with site.same_as profiles Collection entries BlogPosting with dates, image, and author Nested pages BreadcrumbList Pages with faq FAQPage Frontmatter --- title: Shipping less description: What this page ships, and why every byte has to justify itself. updated: 2026-10-01 author: Om Rajguru image: /covers/shipping-less.png image_alt: A page loading with no JavaScript canonical: /posts/shipping-less/ robots: noindex faq: - q: Does Mira ship JavaScript? a: Only a runtime of about 1 KB for transitions and prefetching. --- Key Effect updated The sitemap’s lastmod and the article’s dateModified author The article’s author, otherwise the site image , image_alt The social card for this page, overriding site.image canonical A path or full URL to declare as the canonical page robots Written as a robots meta tag; noindex also removes the page from the sitemap, llms.txt , and search faq A list of q and a , written as FAQPage Site settings { \" site \" : { \" url \" : \" https://example.com \" , \" image \" : \" /og.png \" , \" image_alt \" : \" Example, a site built with"},{"url":"/docs/agents/","title":"Agent surface","description":"Markdown copies of every page, llms.txt, a search index, a content index for MCP, a crawler policy, and structured data, written on every build.","headings":[{"id":"markdown-twins","text":"Markdown twins"},{"id":"llms-txt","text":"llms.txt"},{"id":"search-api","text":"Search API"},{"id":"content-index","text":"Content index"},{"id":"mcp","text":"MCP"},{"id":"crawler-policy","text":"Crawler policy"},{"id":"sitemap-and-feeds","text":"Sitemap and feeds"},{"id":"structured-data","text":"Structured data"},{"id":"stable-markup","text":"Stable markup"}],"text":"All docs Agent surface Markdown copies of every page, llms.txt, a search index, a content index for MCP, a crawler policy, and structured data, written on every build. People read a site through the browser. Agents do better with text, structure, and stable URLs. Mira writes both from the same source on every build, so they never drift apart. Markdown twins Every page has a Markdown version at the same path with .md : Page Twin / /index.md /docs/routing/ /docs/routing.md A twin starts with frontmatter naming the page and its canonical URL: --- title: \"Routing\" url: \" https://mira.example /docs/routing/\" description: \"How files in routes/ become URLs.\" --- # Routing Every .md or .mira file in routes/ is a page… Pages written in Markdown reuse their source. Component pages are converted from their rendered <main> element, keeping headings, lists, links, code, and images and leaving out navigation and scripts. Each page links its twin with <link rel=\"alternate\" type=\"text/markdown\"> . Turn twins off with \"agents\": { \"twins\": false } . llms.txt /llms.txt follows the llms.txt format: the site’s title and description, then every page grouped by collection, each linking to its twin. /llms-full.txt is every twin in one file, for agents that want the whole site in one request. Search API /_mira/search.json lists every page with its title, description, headings, and text. See Search . Content index /_mira/content.json describes the site and lists every collection, with its entry count and field types, and every data file. Each collection’s published entries, with all their fiel"},{"url":"/docs/mcp/","title":"MCP server","description":"Read every part of a Mira site over MCP, from a project on disk or from any deployed site, with a client config you can paste.","headings":[{"id":"connect-to-a-deployed-site","text":"Connect to a deployed site"},{"id":"connect-to-a-project","text":"Connect to a project"},{"id":"tools","text":"Tools"},{"id":"what-a-build-publishes","text":"What a build publishes"},{"id":"security","text":"Security"},{"id":"protocol-details","text":"Protocol details"}],"text":"All docs MCP server Read every part of a Mira site over MCP, from a project on disk or from any deployed site, with a client config you can paste. Every Mira site can be read over the Model Context Protocol: its pages as Markdown, search, each collection’s entries with their fields, data files, and media. mira mcp runs the server over standard input and output, which every MCP client supports. Connect to a deployed site Give --url the address of any site built with Mira, on any host: { \" mcpServers \" : { \" my-site \" : { \" command \" : \" npx \" , \" args \" : [ \" -y \" , \" @miraframework/mira \" , \" mcp \" , \" --url \" , \" https://example.com \" ] } } } Nothing has to be deployed for this to work. Every build publishes the files the server reads: a Markdown copy of each page, the search index, and the content index under /_mira/ . Static hosts such as GitHub Pages and S3 work the same as any other. Connect to a project Point --root at a project on disk. The server rebuilds it into .mira/mcp/ before each answer, so answers match your source as you edit: { \" mcpServers \" : { \" my-site \" : { \" command \" : \" npx \" , \" args \" : [ \" -y \" , \" @miraframework/mira \" , \" mcp \" , \" --root \" , \" /path/to/my-site \" ] } } } If mira is already on your PATH , use \"command\": \"mira\" and drop the first two arguments. Tools Tool Arguments Returns site_info none The site’s title, description, and URL, and every collection (with entry counts and field types) and data file list_pages none Every page’s URL, title, and description read_page url , such as /docs/routing/ The page as Markdown, with its ti"},{"url":"/docs/coding-agents/","title":"Working with coding agents","description":"Agent skills, JSON output, and errors that name the fix, so coding agents build Mira sites correctly on the first attempt.","headings":[{"id":"agents-md","text":"AGENTS.md"},{"id":"agent-skills","text":"Agent skills"},{"id":"json-output","text":"JSON output"},{"id":"errors-an-agent-can-act-on","text":"Errors an agent can act on"},{"id":"reading-the-site-back","text":"Reading the site back"}],"text":"All docs Working with coding agents Agent skills, JSON output, and errors that name the fix, so coding agents build Mira sites correctly on the first attempt. Coding agents build Mira sites for people. Mira gives them predictable conventions, machine readable output, and errors that say how to fix themselves. AGENTS.md mira new writes an AGENTS.md at the project root. It covers the folder conventions, template syntax, transitions, the design tokens, and the commands, in the format coding agents look for. Keep it updated as your project adds its own conventions. Agent skills Install Mira’s skills to give a coding agent the full docs and the working rules for Mira projects: npx skills add buildwithmira/mira Skill For mira Building, editing, checking, and deploying Mira sites, and reading them over MCP mira-migrate Moving a site from another framework and finishing what mira migrate lists for review JSON output mira build --json prints one JSON object to standard output and nothing else: { \" ok \" : true , \" schema \" : 1 , \" report \" : { \" pages \" : [ { \" url \" : \" / \" , \" source \" : \" routes/index.mira \" , \" html_bytes \" : 21890 , \" gzip_bytes \" : 7066 , \" morphs \" : 1 } ] , \" collections \" : { \" posts \" : 2 } , \" runtime_gzip_bytes \" : 1058 , \" outputs \" : [ \" sitemap.xml \" , \" llms.txt \" , \" robots.txt \" ] , \" warnings \" : [ ] , \" timings \" : [ { \" step \" : \" render \" , \" ms \" : 1.5 } ] , \" duration_ms \" : 30.2 } } schema is the output version; it changes only when the shape does. Errors an agent can act on With --json , a failure prints the error in the same structure the"},{"url":"/docs/security/","title":"Security","description":"The policies and defaults that make a Mira site safe without configuration.","headings":[{"id":"content-security-policy","text":"Content security policy"},{"id":"security-headers","text":"Security headers"},{"id":"templates-escape-by-default","text":"Templates escape by default"},{"id":"prefetching-stays-safe","text":"Prefetching stays safe"},{"id":"a-careful-build","text":"A careful build"}],"text":"All docs Security The policies and defaults that make a Mira site safe without configuration. A Mira site is static HTML, which removes most of the attack surface. Mira locks down the rest by default. Content security policy Every page carries a policy in a meta tag, generated from the page itself: default-src 'self'; script-src 'self' 'sha256-…' 'sha256-…'; style-src 'self' 'sha256-…'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self' The hashes cover the page’s inline runtime, its prefetch rules, and its inlined stylesheet, and nothing else. An injected script or style has no matching hash and does not run. Shared element names are compiled into the stylesheet instead of style attributes, so the policy never needs unsafe-inline . Scripts and styles from your own origin are allowed, so a file you put in public/ and link works without changes. Security headers Mira writes a _headers file, read by Netlify and Cloudflare Pages, with the headers a meta tag cannot set: Header Value Content-Security-Policy frame-ancestors 'none'; object-src 'none'; base-uri 'self' X-Frame-Options DENY X-Content-Type-Options nosniff Referrer-Policy strict-origin-when-cross-origin Cross-Origin-Opener-Policy same-origin Cross-Origin-Resource-Policy same-origin Permissions-Policy Camera, microphone, geolocation, payment, and USB off Strict-Transport-Security Two years, including subdomains Twins are served as text/markdown . Turn HSTS off with \"headers\": { \"hsts\": false } until HTTPS is permanent on your domain, or stop writing the file with \"emit\": false . "},{"url":"/docs/errors/","title":"Checks and errors","description":"What the build checks, how errors read, and the dev overlay.","headings":[{"id":"what-fails-the-build","text":"What fails the build"},{"id":"what-warns","text":"What warns"},{"id":"reading-an-error","text":"Reading an error"},{"id":"the-dev-overlay","text":"The dev overlay"},{"id":"in-scripts","text":"In scripts"}],"text":"All docs Checks and errors What the build checks, how errors read, and the dev overlay. Mira checks a site while it builds and stops on anything that would break for a reader. Errors name the file and line and say how to fix the problem. What fails the build Invalid frontmatter, JSON, or YAML Frontmatter that does not match its collection’s schema Template syntax errors, such as an unclosed {#each} A missing layout, or a dynamic route without a collection Two files producing the same URL An internal link or asset that does not exist A shared element name used twice on one page A page over its size budget A missing font file, or an invalid config value What warns Warnings print after the summary and do not stop the build: A link to an anchor that does not exist on its target page An <img> without alt text; use alt=\"\" for decorative images More than one <h1> on a page Each {{ unsafe … }} in a template A generated file skipped because public/ has one with the same name Feeds, sitemap, and canonical URLs skipped because site.url is not set Reading an error ✕ /about/ links to /guide/, which does not exist routes/about.md:7 5 # About 6 › 7 See [the guide](/guide/). hint fix the path, add the page under routes/, or add the file under public/ The first line is the problem. Below it are the file and line, the surrounding source with the failing line marked › , any underlying causes, and a hint. The dev overlay In mira dev , a failed rebuild opens an overlay on the page you are viewing with the same message, location, source, and hint. It also catches errors thrown by scrip"},{"url":"/docs/configuration/","title":"Configuration","description":"Every key in mira.config.json, with types and defaults.","headings":[{"id":"site","text":"site"},{"id":"scheme","text":"scheme"},{"id":"transitions","text":"transitions"},{"id":"prefetch","text":"prefetch"},{"id":"theme","text":"theme"},{"id":"fonts","text":"fonts"},{"id":"collections","text":"collections"},{"id":"agents","text":"agents"},{"id":"headers","text":"headers"},{"id":"hosts","text":"hosts"},{"id":"redirects","text":"redirects"},{"id":"budgets","text":"budgets"}],"text":"All docs Configuration Every key in mira.config.json, with types and defaults. Mira reads mira.config.json from the project root. Every key is optional. Unknown keys fail the build, so a typo never passes silently. { \" site \" : { \" title \" : \" My site \" , \" description \" : \" Notes on design and code. \" , \" url \" : \" https://example.com \" , \" lang \" : \" en \" } , \" scheme \" : \" dark \" , \" transitions \" : { \" default \" : \" fade \" , \" pairs \" : { \" /posts/ -> /posts/* \" : \" slide-up \" } } , \" prefetch \" : { \" eagerness \" : \" moderate \" , \" prerender \" : true } , \" theme \" : { \" ink \" : \" #f4f1ea \" } , \" fonts \" : [ { \" family \" : \" Inter \" , \" src \" : \" /fonts/Inter.woff2 \" , \" preload \" : true } ] , \" collections \" : { \" posts \" : { \" fields \" : { \" title \" : \" string \" , \" date \" : \" date \" } } } , \" agents \" : { \" twins \" : true , \" robots \" : { \" * \" : \" allow \" } } , \" headers \" : { \" emit \" : true , \" hsts \" : true } , \" hosts \" : { \" vercel \" : { } } , \" redirects \" : { \" /old/ \" : \" /new/ \" } , \" budgets \" : { \" page_kb \" : 14 } } site Key Type Default Meaning title string Mira site Site name, used in titles, feeds, and llms.txt description string none Default page description url string none Absolute origin such as https://example.com ; enables canonical URLs, the sitemap, and feeds lang string en The lang attribute of every page image string none Social card image under public/ , such as /og.png image_alt string none Alt text for the social card twitter string none The site’s X handle, such as @example theme_color string none Browser UI color, such as #0b0b0d same_a"},{"url":"/docs/cli/","title":"CLI","description":"Every mira command and option, from creating a site to serving it to agents.","headings":[{"id":"mira-new","text":"mira new"},{"id":"mira-dev","text":"mira dev"},{"id":"mira-build","text":"mira build"},{"id":"mira-migrate","text":"mira migrate"},{"id":"mira-mcp","text":"mira mcp"},{"id":"terminal-output","text":"Terminal output"}],"text":"All docs CLI Every mira command and option, from creating a site to serving it to agents. mira <command> [options] mira --help lists commands, mira <command> --help lists a command’s options, and mira --version prints the version. mira new mira new < dir > Creates a site from the starter in <dir> , which must be new or empty. The starter has a welcome page, an about page, a blog with two posts and a schema, a layout, a favicon, mira.config.json , AGENTS.md , and a .gitignore . mira dev mira dev [ - - root <dir> ] [ - - port <n> ] Option Default Meaning --root . Project folder --port 4321 Port to listen on Builds into .mira/dev/ , serves it at http://localhost:<port> , and rebuilds when a file in the project changes. Changes inside .mira/ , dist/ , .git/ , node_modules/ , and target/ are ignored. Pages reload after each successful build, and failed builds show the error overlay . Drafts are included. The server only listens on 127.0.0.1 . mira build mira build [ - - root <dir> ] [ - - out <dir> ] [ - - json ] [ - - timings ] Option Default Meaning --root . Project folder --out dist Output folder, relative to the project --json off Print a JSON report or error to standard output instead of the summary --timings off Show how long each build step took Exits with a non zero code if the build fails. See Working with coding agents for the JSON shape. mira migrate mira migrate < source > < dest > [ - - from <framework> ] [ - - dry - run ] [ - - json ] Option Default Meaning --from detected nextjs , astro , hugo , jekyll , docusaurus , gatsby , eleventy , vitepress , or markdown -"},{"url":"/docs/deploying/","title":"Deploying","description":"Publish the dist folder to Vercel, Netlify, Cloudflare, GitHub Pages, Firebase, Render, Azure, Docker, Deno, or S3, with each host's config written for you.","headings":[{"id":"what-is-in-dist","text":"What is in dist"},{"id":"before-you-deploy","text":"Before you deploy"},{"id":"hosts","text":"Hosts"},{"id":"redirects","text":"Redirects"},{"id":"checking-a-deploy","text":"Checking a deploy"},{"id":"clean-urls","text":"Clean URLs"},{"id":"caching","text":"Caching"}],"text":"All docs Deploying Publish the dist folder to Vercel, Netlify, Cloudflare, GitHub Pages, Firebase, Render, Azure, Docker, Deno, or S3, with each host's config written for you. mira build writes a complete static site to dist/ . Deploying is publishing that folder. Name your hosts in mira.config.json , and Mira writes each host’s own config file on every build, so headers, clean URLs, the 404 page, redirects, and Markdown twins behave the same everywhere. { \" site \" : { \" url \" : \" https://example.com \" } , \" hosts \" : { \" vercel \" : { } , \" netlify \" : { } } } What is in dist Path Contents index.html , */index.html Pages 404.html The not found page *.md Markdown twins llms.txt , llms-full.txt Agent indexes sitemap.xml , */rss.xml When site.url is set robots.txt Crawler policy media/ , media.json Media frames and their manifest _headers , _redirects For Netlify and Cloudflare Pages vercel.json For Vercel, when dist/ is the project root _mira/ The search index, and scripts a page uses everything from public/ As is Before you deploy Set site.url to your production origin so canonical URLs, the sitemap, and feeds use absolute links. Hosts Each key under hosts writes that host’s config. Files go in the project root unless noted. Mira only replaces files it wrote itself: if a config file you wrote by hand is in the way, the build stops and says so, and your file is left alone. Host Key Mira writes Set up Vercel vercel vercel.json Import the repository. No build command is needed. Netlify netlify netlify.toml , dist/_redirects Import the repository. Cloudflare Pages cloudflare"},{"url":"/docs/migrating/","title":"Migrating to Mira","description":"Move a Next.js, Astro, Hugo, Jekyll, Docusaurus, Gatsby, Eleventy, or VitePress site to Mira with one command, keeping every URL.","headings":[{"id":"safe-by-design","text":"Safe by design"},{"id":"what-it-moves","text":"What it moves"},{"id":"per-framework","text":"Per framework"},{"id":"after-migrating","text":"After migrating"},{"id":"for-agents","text":"For agents"},{"id":"frontmatter-names","text":"Frontmatter names"}],"text":"All docs Migrating to Mira Move a Next.js, Astro, Hugo, Jekyll, Docusaurus, Gatsby, Eleventy, or VitePress site to Mira with one command, keeping every URL. mira migrate moves a content site from another framework into a new Mira project. It brings over pages, posts, frontmatter, images, and static files. It writes a redirect for every URL that changes, then builds the new project to prove it works. mira migrate ./old-site ./new-site The framework is detected from package.json or the project’s files. To name it yourself, pass --from : mira migrate ./old-site ./new-site -- from hugo Safe by design Nothing in the old project runs. Config files, components, and templates are read as text. No JavaScript, Go templates, or Liquid execute. The old project is never changed. It is only read. The destination must be a new or empty folder outside the old project. No network. Remote images are not downloaded. Each one becomes a link and is listed for review. Files never leave the project. A relative image is followed only to a regular file inside the old project, and symlinks are skipped. Nothing is lost silently. Anything that cannot be converted is kept in a <!-- mira migrate: … --> comment and listed, with its file and line, in MIGRATION.md . What it moves From the old site In the Mira project Markdown and MDX pages routes/<path>/index.md , at the same URL Posts in posts/ , _posts/ , blog/ , articles/ , news/ , notes/ , writing/ , changelog/ , journal/ A collection in content/<name>/ , with routes/<name>/[slug].mira and an index page YAML ( --- ) or TOML ( +++ ) frontmatter YAML"},{"url":"/docs/","title":"Docs","description":"Install Mira, build your first site, and deploy it, with a reference for every config key and command.","headings":[{"id":"dh-start","text":"Start here"},{"id":"dh-agents","text":"Read these docs from your agent."}],"text":"Docs From npm create mira to a deployed site, plus a reference for every config key and command. Start here 01 Create a site npm create mira@latest 02 Write and preview npm run dev 03 Build and deploy npm run build Getting started Install Mira and ship a first site. Introduction Installation Quick start Project structure Building pages Routes, templates, layouts, collections, and Markdown. Routing Templates Layouts Content collections Markdown Data files Motion Page transitions and elements that travel between pages. Page transitions Shared elements Styling Theme tokens, components, fonts, and images. Theming Components Fonts Media frames Performance What keeps pages small, and the search index. Performance Search Agents SEO, AI search, Markdown copies, and the MCP server. SEO and AI search Agent surface MCP server Working with coding agents Quality and security Security defaults and the checks every build runs. Security Checks and errors Migrating Move a site from another framework. Migrating to Mira Reference Every config key, command, and host. Configuration CLI Deploying Read these docs from your agent. Every Mira site works as an MCP server, these docs included. Add this to your MCP client and it can search every page, read it as Markdown, and list the changelog. \"mira-docs\" : { \"command\": \"npx\", \"args\": [\"-y\", \"@miraframework/mira\", \"mcp\", \"--url\", \"https://mira.omrajguru.site\"] }"},{"url":"/","title":"Pages that move","description":"Mira is an open source static site framework for sites that arrive fast, move like apps, and read as clearly to agents as they do to people.","headings":[{"id":"hosting-title","text":"Ships anywhere static files do."},{"id":"agents-title","text":"Your site, served to agents."},{"id":"caps-title","text":"Also in every build."},{"id":"migrate-title","text":"Bring your site with you."},{"id":"finale-title","text":"Start a site in one command."}],"text":"Pages that move. An open source static site framework. Write Markdown, ship plain HTML that loads fast, animates between pages, and reads as well to agents as it does to people. 1 KB runtime 0 KB app JavaScript Any static host npm create mira@latest Quick start GitHub 0.1.2 The README on npm, and releases you can verify Elements travel between pages. Add mira-morph to a title or image and it animates into its match on the next page. Back plays it in reverse. Ready before the click. Links prefetch on hover and prerender on press, so the next page is usually already there. # ## A Markdown copy of every page. Add .md to any URL. Agents get clean text with a canonical link; people get the designed page. Styled from the first build. A theme, type scale, and components come with every project. Change them in mira.config.json . Ships anywhere static files do. mira build writes one folder of plain HTML, Markdown, and assets. Name your hosts in mira.config.json and each build writes their own config, so headers, clean URLs, the 404 page, and redirects behave the same on all of them. Firebase, Render, Azure, and Deno Deploy are covered too. routes/ · content/ mira build dist/ Vercel vercel.json Netlify netlify.toml Cloudflare Pages wrangler.toml GitHub Pages Actions workflow Amazon S3 CloudFront function Docker and nginx Dockerfile, nginx.conf Your site, served to agents. Run mira mcp and any MCP client can list, search, and read every page, rebuilt fresh for each call. Add it to a client with npx @miraframework/mira mcp . Every page also has a Markdown twin, and each build writes l"}]