From impeccable
Expert Astro development with content-driven sites, island architecture, and zero-JS-by-default patterns
How this skill is triggered — by the user, by Claude, or both
Slash command
/impeccable:astroThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert Astro developer. Apply these principles when building content-driven websites and applications.
You are an expert Astro developer. Apply these principles when building content-driven websites and applications.
---
// Server-side code runs at build time
interface Props {
title: string;
description?: string;
}
const { title, description = "Default description" } = Astro.props;
const posts = await fetch("https://api.example.com/posts").then(r => r.json());
---
<section class="hero">
<h1>{title}</h1>
{description && <p>{description}</p>}
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.slug}`}>{post.title}</a>
</li>
))}
</ul>
</section>
<style>
.hero {
padding: 4rem 2rem;
text-align: center;
}
h1 {
font-size: 2.5rem;
background: linear-gradient(to right, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
---
import StaticHeader from "../components/Header.astro";
import InteractiveSearch from "../components/Search.tsx";
import LazyCarousel from "../components/Carousel.svelte";
---
<!-- No JS shipped for static components -->
<StaticHeader />
<!-- Hydrated on page load -->
<InteractiveSearch client:load />
<!-- Hydrated when visible in viewport -->
<LazyCarousel client:visible />
<!-- Hydrated only when idle -->
<NewsletterForm client:idle />
<!-- Hydrated on media query match -->
<MobileMenu client:media="(max-width: 768px)" />
import { defineCollection, z } from "astro:content";
const blog = defineCollection({
type: "content",
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
heroImage: z.string().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
---
import { getCollection } from "astro:content";
const posts = await getCollection("blog", ({ data }) => !data.draft);
const sorted = posts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
---
{sorted.map((post) => (
<article>
<time datetime={post.data.pubDate.toISOString()}>
{post.data.pubDate.toLocaleDateString()}
</time>
<h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
<p>{post.data.description}</p>
</article>
))}
src/pages/
├── index.astro → /
├── about.astro → /about
├── blog/
│ ├── index.astro → /blog
│ └── [slug].astro → /blog/:slug (dynamic)
└── [...slug].astro → catch-all
---
// src/pages/blog/[slug].astro
import { getCollection } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
---
import { Image } from "astro:assets";
import heroImage from "../assets/hero.jpg";
---
<!-- Automatic optimization: format conversion, srcset, lazy loading -->
<Image src={heroImage} alt="Hero image" width={1200} height={600} />
---
import { ViewTransitions } from "astro:transitions";
---
<head>
<ViewTransitions />
</head>
<!-- Per-element transitions -->
<h1 transition:name="title" transition:animate="slide">
Page Title
</h1>
.astro components for purely static content — zero JS shippedclient:visible for below-the-fold interactive componentsgetStaticPaths() for SSG dynamic routesclient:load on everything — defeats the purpose of Astro.tsx/.vue components when a .astro component sufficesastro:assets instead of plain <img>npx claudepluginhub firdausmntp/techneuma --plugin impeccableGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.