codeLabs

Astro + Tailwind + TypeScript starter setup

Astro & static sites · updated may 2026

astrotailwindtypescriptsetup

Every client site I start now begins from the same base: Astro, Tailwind, TypeScript in strict mode, Prettier with the Tailwind plugin. It takes about ten minutes to get right and saves a lot of later cleanup, so here’s the actual sequence rather than the abbreviated version in the docs.

Start with the official scaffold and pick TypeScript strict when it asks:

npm create astro@latest -- --template minimal --typescript strict

Add Tailwind through Astro’s own integration rather than hand-wiring PostCSS yourself — it used to require more manual config, but the current integration handles the Vite plugin wiring for you:

npx astro add tailwind

That command edits astro.config.mjs for you, so check the diff rather than trusting it blindly, especially if you already had a custom Vite config in there. On a couple of projects it’s dropped an existing plugin entry because the file didn’t parse the way the CLI expected.

The part people skip is Prettier with prettier-plugin-tailwindcss. Without it your class strings end up in whatever order you typed them, which turns into a genuine readability problem once a className string hits fifteen or twenty classes. Install it alongside prettier-plugin-astro so both file types get formatted consistently:

npm install -D prettier prettier-plugin-astro prettier-plugin-tailwindcss

Plugin order in .prettierrc matters here — Astro’s plugin needs to run its own way, and Tailwind’s class-sorting plugin should generally go last in the plugins array, or class ordering silently stops applying.

For TypeScript, I turn on strict mode at scaffold time rather than adding it later, because retrofitting strict mode onto a codebase that’s grown loose is a much bigger job than starting with it. I also set verbatimModuleSyntax in tsconfig.json, which forces explicit import type for type-only imports — a small thing, but it catches a class of bundling issues before they happen rather than after.

Last piece: tailwind-merge, if you’re building reusable Astro components (Button, Card, Section — anything that takes a class prop and needs sane conflict resolution between default classes and caller-supplied overrides). Without it, a caller passing class="p-4" to override a component’s default p-2 just appends the class rather than replacing it, and Tailwind’s cascade order decides which one wins, which is rarely what you meant. twMerge resolves that correctly by understanding which Tailwind classes are mutually exclusive.

npm install tailwind-merge

With all four in place — Astro, Tailwind via the official integration, strict TypeScript, and Prettier with the Tailwind sort plugin — new components start consistent instead of needing a pass of cleanup once the project has grown past the first few files.

Nic

builder, codelabs.com.au

Stay up to date with AI coding

New articles roughly every couple of weeks. No spam, unsubscribe any time.