AstroWind is a free, open-source website template built with Astro v6 and Tailwind CSS v4. It generates a fully static site optimized for performance, SEO, and accessibility.
Stack: Astro v6 | Tailwind CSS v4 | TypeScript 5.9 | MDX | Sharp
| Command | Purpose |
|---|---|
npm run dev |
Start dev server at localhost:4321 |
npm run build |
Production build to ./dist/ |
npm run preview |
Preview production build locally |
npm run check |
Run astro check + ESLint + Prettier |
npm run fix |
Auto-fix ESLint + Prettier issues |
Node.js requirement: >= 22.12.0
src/
assets/styles/tailwind.css # Tailwind v4 config (themes, utilities, plugins)
components/
common/ # Shared: Image, Metadata, Analytics, ToggleTheme
ui/ # Primitives: Button, Headline, WidgetWrapper, ItemGrid
widgets/ # Page sections: Hero, Features, Pricing, Header, Footer
blog/ # Blog: SinglePost, List, Pagination, Tags
CustomStyles.astro # CSS variables for colors and fonts
content.config.ts # Content Collections schema (Astro v6 location)
data/post/ # Blog posts (.md, .mdx)
layouts/ # Layout.astro, PageLayout.astro, MarkdownLayout.astro
pages/ # File-based routing
utils/ # blog.ts, images.ts, permalinks.ts, frontmatter.ts
config.yaml # Site configuration (loaded as virtual module)
navigation.ts # Navigation structure
types.d.ts # TypeScript type definitions
vendor/integration/ # Custom Astro integration for config loading
Use ~/ to import from src/:
import Image from '~/components/common/Image.astro';
import { SITE } from 'astrowind:config';Site config lives in src/config.yaml and is loaded as a Vite virtual module astrowind:config by the custom integration in vendor/integration/. Exports: SITE, I18N, METADATA, APP_BLOG, UI, ANALYTICS.
Configuration is CSS-first in src/assets/styles/tailwind.css:
- Theme tokens:
@theme { --color-primary: var(--aw-color-primary); ... } - Custom utilities:
@utility bg-page { ... } - Dark mode: Class-based via
@variant dark (&:where(.dark, .dark *)) - Plugins:
@plugin "@tailwindcss/typography" - Custom variant:
@custom-variant intersect (&:not([no-intersect]))
CSS variables for colors/fonts are defined in src/components/CustomStyles.astro with light/dark theme variants.
The Vite plugin @tailwindcss/vite is configured in astro.config.ts (not as an Astro integration).
Components use twMerge from tailwind-merge v3 for conditional class composition.
Defined in src/content.config.ts using the Astro v6 Content Layer API with glob() loader. Posts are in src/data/post/ as .md or .mdx files.
Post frontmatter: title (required), publishDate, updateDate, draft, excerpt, image, category, tags, author, metadata.
- Props extend interfaces from
~/types - Use
class:listfor conditional classes - Use
twMerge()when accepting className overrides - Use named slots for layout composition
- Widget components accept standardized props (see
~/types)
src/components/common/Image.astro supports:
- Local images via
astro:assets(optimized by Sharp) - Remote images via Unpic CDN
- Allowed domains (for providers Unpic can't detect, processed by Sharp):
cdn.pixabay.com
Hero images use loading="eager" and fetchpriority="high".
After changes, always verify:
npm run buildsucceedsnpm run checkpasses (astro check + ESLint + Prettier)- Visual check in browser: homepage, blog, dark mode, mobile menu