The problem
When you are new to HTML and CSS, Aero can be confusing at first because Aero files look very close to normal web files. That is a strength, but it is easy to miss which parts come from the browser and which parts only work because Aero interprets them. For example, all of this can appear in one file:What this looks like without Aero
In plain web development, the browser understands HTML elements, CSS rules, and ordinary client-side JavaScript. It does not understand things like:{ title }inside HTML<script is:build>if,for,switch, orpropsas template directives- File-based routing from your
client/pages/folder - Importing an
.htmlfile and then writing<card-component>
How Aero helps
Aero keeps most of your authoring model close to the web platform:- Your files are still
.html - Your styles are still CSS
- Your client scripts are still browser JavaScript
- HTMX and Alpine attributes are preserved
- The framework adds a small template and build layer on top
What stays native in Aero
These things are still ordinary web-platform features:- Normal HTML elements like
<div>,<p>,<a>,<img>,<form>, and<template> - Normal CSS inside
<style> - Normal browser JavaScript inside a plain
<script> - Normal HTML attributes like
class,id,href,src,alt,aria-*, anddata-* - Normal URLs and links
- Normal HTMX attributes like
hx-getandhx-post - Normal Alpine attributes like
x-data,x-show,:class, and@click
Quick rule of thumb
- If the browser can understand it on its own, it is native web.
- If Aero evaluates it during build time or render time, it is Aero behavior.
<slot>is a native HTML element, but Aero uses it as part of its layout and component system.data-*is native HTML syntax, butdata-if,data-for,data-switch, anddata-propsare Aero directives.- Plain
<script>is native, but Aero can still bundle local scripts and pass data into them withprops.
Aero-only template syntax
{ } interpolation
Plain HTML has no built-in way to evaluate JavaScript expressions inside markup at build time. With Aero, { expression } is evaluated and the result is inserted into the output. See Templates.
if, else-if, and else
HTML has no native conditional rendering syntax. Aero adds conditional directives on elements. See Templates.
for and data-for
HTML has no native loop syntax. Aero adds loop directives so one element or fragment can repeat. See Templates.
switch, case, and default
Aero adds switch, case, and default directives for matching one value against several cases. See Templates.
props and data-props
Aero adds props for components, client scripts, and styles. See Templates.
<script is:build>
In plain HTML, a <script> tag is a browser script. Aero adds is:build so code runs in Node at build time (or request time when applicable), not in the browser. See Scripts.
<script is:inline> and <script is:blocking>
Aero adds is:inline to leave a script in place and is:blocking to hoist a script into <head>. See Scripts.
Imported .html components and layouts
HTML does not have a native file-import-based component system. In Aero you import .html templates and use them as components or layouts. See Templates.
Slots and slot passthrough
<slot> is native HTML; using it in Aero’s layout and component model, including slot passthrough across nested layouts, is Aero behavior. See Templates.
Wrapperless <template> directives
Plain <template> is native and stays inert in the browser. <template if>, <template data-for>, and <template switch> get special compiler behavior. See The HTML template element.
Framework features beyond native web
File-based routing and getStaticPaths()
Files in client/pages/ become URLs; bracket routes use getStaticPaths() for static generation. See Routing.
Content collections
Validated collections,getCollection(), and render(). See Content.
Optional Nitro
Withserver: true, Nitro provides API routes, middleware, storage, tasks, and deployment presets. See Server.
Vite bundling and HMR
Bundled local scripts, asset processing, and HMR in development. See Importing and bundling.Tooling
VS Code extension,aero check, and path aliases. See CLI and Configuration.
Optional image optimization and incremental builds
See Image optimization and Incremental builds.Native vs Aero cheat sheet
| What you see | Native web or Aero? | What handles it |
|---|---|---|
<div>, <p>, <a> | Native web | Browser |
<style> with normal CSS | Native web | Browser |
Plain <script> | Native web | Browser (Vite bundles local modules) |
hx-*, x-*, :class, @click | Not Aero syntax | HTMX or Alpine in the browser |
{ title } | Aero | Aero template engine |
if, else-if, else | Aero | Aero template engine |
for, data-for | Aero | Aero template engine |
switch, case, default | Aero | Aero template engine |
props, data-props | Aero | Aero template engine |
<script is:build> | Aero | Build or SSR runtime |
<script is:inline> / is:blocking | Aero on native element | Aero compiler |
<header-component> from header.html | Aero | Aero component system |
<slot> in an Aero layout | Mixed | Native element used by Aero composition |
<template data-for> | Mixed | Native element with Aero directive behavior |
client/pages/about.html → /about | Aero | Aero routing |
[slug].html + getStaticPaths() | Aero | Aero routing and build |
getCollection() and render() | Aero | Aero content layer |
server/api/* with server: true | Aero app capability | Nitro |
@components/header | Aero | Toolchain path alias |
| HMR, build output, asset hashing | Aero app capability | Vite |
Mental model
- The browser still handles normal HTML, CSS, and client JavaScript.
- Aero adds a template layer, a file-based project structure, and a build pipeline.
- When you are unsure, ask: “Would this still mean anything in a plain HTML file opened directly by the browser?”