Discover our brand new website!
Home Projects Documentation Articles

Published on Apr 30, 2024

Introducing Astro Theme Provider

Astro Theme Provider is a tool that allows you to author themes for Astro like a normal project and export your work as an integration for others to use.

Problems with current theme practices

In Astro, typically a theme is a full project published as a template that users can clone and customize. Project templates are a common pattern and have lots of use cases, but they also have downsides that theme authors may not always be aware of.

One of the most significant downsides to project templates is that they are not beginner-friendly. The main demographic for theme users are people who are new to Astro and web development in general. Cloning and editing a project template as a beginner can be challenging. Project templates often times use lots of different technologies and can be bloated with files beginners may never need to edit. Also, there are no official conventions for authoring templates. Most templates use different combinations of patterns and structures. For example, many templates have a config file for customization, but the location of the file and its options vary depending on the template. Learning how to use a template while also learning how to use Astro can be confusing.

Project templates also have some more practical downsides. Merging improvements from a template can be difficult if not impossible after customizing your local copy. Also, templates cannot be easily added to existing Astro projects. Adding a template to an existing project requires manually splicing code from a template into a project.

A better way to create themes

A better way to create more user-friendly themes is shifting away from project templates and towards Astro integrations. Using an integration to author a theme has many different advantages over a traditional template. One of the largest advantages is that they can be published and consumed as NPM packages. This allows users to add themes to existing projects and upgrade them at any time.

Although theme integrations can be more user-friendly than project templates, they come at the cost of being harder to create. They require a lot of boilerplate and a lower level knowledge of Astro and Vite making it inaccessible for a lot of developers.

Astro Theme Provider solves this by making it easier for theme authors to create theme integrations without having to write any integration code. Themes can be authored similar to a normal Astro project and be exported for others to use with a single function call.

  • Directorypackage/
    • Directorypublic/
    • Directorysrc/
      • Directoryassets/
      • Directorycomponents/
      • Directorycss/
      • Directorylayouts/
      • Directorypages/
    • index.ts
    • package.json

import { z } from 'astro/zod';
import defineTheme from 'astro-theme-provider';
export default defineTheme({
name: "my-theme",
schema: z.object({
title: z.string()

After creating your theme, it can be used inside an Astro project as an integration:

import { defineConfig } from "astro/config";
import myTheme from "my-theme";
export default defineConfig({
integrations: [
config: {
title: "Welcome to my theme!",

Real world example

Astro Theme Provider is inspired by Starlight, Astro’s official documentation theme. Starlight is a theme integration that allows you to build a full documentation website with a config object and some markdown. Its ease of setup and use has made Starlight one of the most popular themes for Astro. Its success proves that theme integrations are a powerful pattern that have been under utilized in the Astro ecosystem.

What’s Next

We’re excited to share that Astro Theme Provider is in beta as of today. What’s next? - We’re working on improving the experience and shaping a stable version, but we need your help! We encourage contributions of any kind! You can check out the Project on GitHub and join us on Discord!

Introducing Astro Theme Provider © 2024 by Bryce Russell, is licensed under CC BY-NC 4.0