README.md

June 12, 2026 · View on GitHub

Showcase Card

astro-erudite

Stargazers Astro Version Dependencies License

astro-erudite is enscribe's opinionated, unstyled static blogging template built with Astro and native CSS. astro-erudite uses no UI framework, no CSS framework, and contains minimal dependencies.

Preview 1Preview 2
Preview 3Preview 4

Important

astro-erudite has recently been updated to v2. To learn what changed and why, read the following blog post: Introducing astro-erudite v2. If you're migrating an existing v1 project, see breaking changes.


Community examples

Below are some fantastic examples of websites based on this template. If you wish to add your site to this list, open a pull request!

SiteAuthorTagsSource
enscribe.dev@jktrnportfolio, interactive
emile.sh@echoghiminimal, flexoki
decentparadox.me@decentparadoxportfolio, sci-fi
flocto.github.io@floctoblog
dumbprism.me@dumbprismportfolio, bento
hyuki.dev@snow0406minimal, blog
ldd.cc@xJoyLublog
rezarezvan.com@rezaarezvanacademic, blog
blog.z0x.ca@z0xminimal
angelaytchan.net@wispyplantportfolio, art
kaezr.xyz@kaezrrminimal, portfolio
worldwidewong@brendanwong-webportfolio, gallery
bgajjala.dev@bgajjala8minimal, blog
ankitz007.vercel.app@ankitz007blog
sadman.ca@sadmancablog, media
marcel-to.vercel.app@Marcel-TOportfolio, docs
merox.dev@meroxdotdevblog, devops, homelab
Off by One@cdurukengineering, blog
holywater.dev@holywater2372cybersecurity, blog
theinfinull.com@theinfinulldev, portfolio, blog
chai-pin-zheng.xyz@Ducksssportfolio, interactive, blog, ascii
nightxade.dev@nightxadeblog, portfolio
xingpingcn.top@xingpingcnblog, chinese

Features

  • A design system built entirely on native CSS, using autonomous custom elements and Utopia fluid type and space scales.
  • The ridiculously fast Sätteri Markdown processor (written in Rust)
  • Expressive Code for code blocks and inline code, with `code{:lang}` annotations and TextMate scope highlighting.
  • LaTeX\LaTeX math rendered to browser-native and lightweight MathML via Temml.
  • Subposts for organizing series, rendered as one continuous scrollable document.
  • A fully responsive table of contents with active scrollspy highlighting.
  • Clickable heading anchors for permalinking to any section.
  • GitHub-style callouts/alerts via ::: directives.
  • SEO optimization with granular metadata and Open Graph tag control for each post.
  • RSS feed and sitemap generation.
  • Author profiles with a dedicated authors page and multi-author post support.
  • Post tags with a dedicated tags page for categorization and discovery.

Getting started

  1. Hit “Use this template”, the big green button on the top right, to create a new repository in your own GitHub account with this template.

  2. Clone the repository:

    git clone https://github.com/[YOUR_USERNAME]/[YOUR_REPO_NAME].git
    cd [YOUR_REPO_NAME]
    
  3. Install dependencies:

    bun install
    
  4. Start the development server:

    bun dev
    
  5. Open your browser and visit http://localhost:4321 to get started. The following commands are also available:

    CommandDescription
    bun run buildBuild the production site to dist/
    bun run previewPreview the built project locally
    bun run astroRun Astro CLI commands
    bun run formatFormat all files using Biome
    bun run format:checkCheck formatting without writing

Site configuration

Edit the src/consts.ts file to update your site's metadata, navigation links, and social links:

export const SITE = {
  title: "astro-erudite",
  description: "An opinionated, unstyled blogging template built with Astro.",
  locale: "en-US",
  dir: "ltr",
  defaultPageImage: "/static/opengraph-image.png",
  defaultPostImage: "/static/1200x630.png",
} as const

export const NAVIGATION = [
  { href: "/blog", label: "Blog" },
  // ...
]

export const SOCIALS: { href: string; label: string; icon: SvgComponent }[] = [
  { href: "https://github.com/jktrn", label: "GitHub", icon: GitHub },
  // ...
]

Your site's production URL is configurable in astro.config.ts as the site field, which is used for the sitemap, RSS feed, and canonical URLs.

Color palette

Colors are defined in src/styles/color.css using the Radix Colors scales. Each step carries a light/dark pair via light-dark() and the semantic tokens point at the scale, so the site respects system preference out of the box and the theme toggle only stores an override:

:root {
  --gray-1:  light-dark(#fcfcfc, #111111);
  /* ... */
  --gray-12: light-dark(#202020, #eeeeee);

  --background:       var(--gray-1);
  --foreground:       var(--gray-12);
  --muted-foreground: var(--gray-11);
  --border:           var(--gray-6);
  /* ... */

  color-scheme: light dark;
}

Favicons

Favicons are generated using RealFaviconGenerator. To adjust the favicons, replace the files in the public/ directory (such as favicon.ico, favicon.svg, apple-touch-icon.png, etc.) with your own. After updating the favicon files, you'll also need to adjust the references in src/components/MetaHead.astro to match your new favicon filenames and paths:

<!-- Replace these with the generated meta tags -->
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="astro-erudite" />
<link rel="manifest" href="/site.webmanifest" />

Adding content

Blog posts

Add new blog posts as Markdown files in the src/content/blog/ directory, either as a bare your-post.md or as a your-post/index.md folder (which lets you colocate assets). Use the following frontmatter structure:

---
title: "Your Post Title"
description: "A brief description of your post!"
date: 2026-01-01
authors:
  - enscribe
image: ./assets/banner.png
tags:
  - tag1
  - tag2
---

The blog post schema is defined as follows:

FieldType (Zod)RequirementsRequired
titlestringShould be ≤60 characters.Yes
descriptionstringShould be ≤155 characters.Yes
datecoerce.date()Must be in YYYY-MM-DD format.Yes
ordernumberSort order for subposts within a series. Defaults to 0 if not provided.Optional
tagsstring[]Preferably use kebab-case for these.Optional
authorsreference("authors")[]Each entry must match the id of a file in src/content/authors/ (e.g. if their file is named jane-doe.md, use jane-doe in the array). Validated at build time.Yes
imageimage()Should be exactly 1200px × 630px.Optional
draftbooleanDefaults to false if not provided. You can also prefix a filename with _ to hide it from the content loader entirely.Optional

Subposts

A post becomes a series by nesting sibling Markdown files next to its index.md:

src/content/blog/
├── a-standalone-post.md
└── my-series/
    ├── index.md
    ├── getting-started.md
    └── going-further.md

The entire series renders as one continuous document, with the address bar syncing as you scroll between parts. Every subpost still gets its own URL (/blog/my-series/getting-started). Use the order frontmatter field to control the sequence. Only one level of nesting is supported, so files nested any deeper are ignored.

Markdown extensions

A few authoring features exist that extend beyond standard Markdown:

  • Callouts use the directive syntax, with five variants (note, tip, warning, caution, important) rendered as collapsible <details> elements. Append {closed} to start one collapsed:

    :::note[An optional custom title]
    Hello, world!
    :::
    
  • Math is written as $inline$ or $$display$$ LaTeX\LaTeX and rendered to MathML at build time.

  • Inline code ending in an annotation gets syntax highlighting: `const x = 1{:ts}` highlights as TypeScript, and `text{:.string}` paints with the theme's color for a TextMate scope.

Authors

Add author information in src/content/authors/ as Markdown files. A file named [author-name].md can be associated with a blog post if "author-name" (the id) is added to the authors field:

---
name: "enscribe"
pronouns: "he/him"
avatar: "https://avatars.githubusercontent.com/u/71956291?v=4"
bio: "d(-_-)b"
mail: "jason@enscribe.dev"
socials:
  website: "https://enscribe.dev"
  twitter: "https://twitter.com/enscrbe"
  github: "https://github.com/jktrn"
---

The author schema is defined as follows:

FieldType (Zod)RequirementsRequired
namestringn/aYes
pronounsstringn/aOptional
avatarurl() or string.startsWith("/")Should be either a valid URL or a path starting with /.Yes
biostringn/aOptional
mailemail()Must be a valid email address.Optional
socialsrecord(string, url())A map of any label you like to a valid URL. Each label is matched to an icon in src/components/SocialIcons.astro.Optional

Projects

Add projects in src/content/projects/ as Markdown files:

---
name: "Project A"
description: "This is an example project description! You should replace this with a description of your own project."
tags: ["Framework A", "Library B", "Tool C", "Resource D"]
image: "./placeholder.png"
link: "https://example.com"
startDate: "2024-01-01"
endDate: "2024-02-01"
---

The project schema is defined as follows:

FieldType (Zod)RequirementsRequired
namestringn/aYes
descriptionstringn/aYes
linkurl()Must be a valid URL.Yes
tagsstring[]n/aOptional
imageimage()Should be exactly 1200px × 630px.Optional
startDatecoerce.date()Must be in YYYY-MM-DD format.Optional
endDatecoerce.date()Must be in YYYY-MM-DD format.Optional

License

This project is open source and available under the MIT License.


Star history

Star History Chart

Built with ♥ by enscribe!