Model or dataset
alxshelepenok/lumen avatar
alxshelepenok/lumen

lumen: an Astro static blog template with connected JSON-LD, llms.txt and zero client JavaScript

A constantly evolving and thoughtful architecture for creating static blogs.

2,018 stars635 forksTypeScriptMIT

At a glance

What is it?
lumen is an Astro static blog template at version 3.0.9 that ships four direct dependencies, zero client JavaScript by default and a grounded JSON-LD graph across five node types. It requires Bun, includes Sentry as a direct dependency and generates llms.txt for LLM indexing.
Who is it for?
Use lumen if you want an Astro static blog with pre-configured JSON-LD forming a connected graph, llms.txt generation and zero client JavaScript, and your team already uses Sentry. Skip it if Sentry is not acceptable as a direct dependency, because the README gives no documented removal path.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four direct dependencies and 0 KB of client JavaScript by default

The dependency count for lumen is intentionally small. The `dependencies` field in package.json lists exactly four entries: Astro at 7.3.3, @astrojs/sitemap at 3.7.4, @astrojs/markdown-remark at 7.3.1 and @sentry/astro at 10.75.0. Everything else runs as a dev dependency at build time and ships nothing to the browser.

Zero client JavaScript is the default outcome of the Astro SSG approach: every page compiles to plain HTML during the build with no hydration step. That constraint eliminates the category of bugs caused by JavaScript loading asynchronously after initial paint, and it also means the page weight stays low by default rather than requiring manual optimization passes.

Cumulative layout shift is explicitly listed as zero. Asynchronous image loading uses `decoding="async"` and `loading="lazy"` as attributes baked directly into the generated HTML, not applied by a JavaScript handler at runtime. Layout remains stable before images finish loading, and no browser-side JavaScript is required to enforce that stability.

The JSON-LD graph links five node types through stable hash-fragment IDs

Structured data in lumen is not a collection of isolated JSON-LD blocks emitted per page in isolation. Five node types form one connected graph: WebSite, Blog, BlogPosting, WebPage and Person are explicitly linked rather than treated as independent entities.

Each node carries a stable ID built from a canonical URL with a hash fragment: `#web` for WebSite, `#blog` for Blog, `#article` for BlogPosting and `#person` for Person. Using a canonical URL plus a fragment rather than a random identifier means the IDs remain stable across builds and can be joined across pages by any system that consumes JSON-LD, which is particularly relevant for search engine knowledge graphs and AI crawlers that merge data across sources.

The project claims 100% consistency between what the JSON-LD graph asserts and what the visible page content says. That constraint prevents the common failure mode where a JSON-LD title and a rendered H1 diverge after an edit. An audit script at `internal/testing/audit.ts` is available as the `audit` entry in package.json, suggesting a machine-checkable test backs this consistency claim rather than relying on manual review.

llms.txt and raw Markdown at stable URLs for LLM and RAG workflows

Alongside the standard sitemap, lumen generates two files in the root directory: `llms.txt` and `llms-full.txt`. The first is a condensed site summary; the second is a full text index of the entire site. Both are designed for AI systems that crawl for context rather than for human readers, and the distinction from sitemap.xml is that these files expose prose rather than URL listings.

Every post also serves its source Markdown at a stable URL. That URL is intentional and documented as providing clean raw Markdown with no HTML noise, layout or scripts, suited for loading into a RAG context window. For teams building internal documentation that also feeds into an LLM retrieval pipeline, this removes the step of scraping and cleaning HTML before ingestion.

For a personal blog where LLM indexing is not a goal, these files generate unconditionally at build time anyway. They appear in the public output regardless of need. The README documents no configuration switch to suppress them, so teams with a reason to keep raw Markdown private should account for that before adopting the template, since disabling the Markdown endpoint requires modifying the template code rather than flipping an option.

Bun is the required runtime, and the quick start is two commands from the README

Lumen requires Bun as both the package manager and the runtime. Node.js is not documented as an alternative, and the `bun.lock` file at the repository root confirms that the lockfile format is Bun's own rather than npm's or yarn's. For a CI environment or a hosting provider that provisions only Node.js tooling, this is a real setup cost rather than a minor configuration change.

Starting the project takes two commands from the README:

bash
bun install
bun run start

`bun run start` maps to `astro dev` in the `scripts` section of package.json, starting the local Astro development server. The `build` script maps to `astro build` for a production build, and the `serve` script maps to `astro preview` for reviewing the production output locally before deployment.

Because lumen is a template rather than a published npm package, the workflow is to clone the repository and modify the content directly. The `content/` directory at the repository root holds the blog posts. There is no scaffolding CLI entry documented in the README.

Sentry is a direct dependency at version 10.75.0, with no documented opt-out

Sentry appears in the `dependencies` field of package.json as `@sentry/astro` at version 10.75.0, sitting alongside Astro itself as a runtime dependency rather than in devDependencies where build-time tools live. This distinction matters in practice: the package loads at runtime, not just at build time.

Deploying lumen without Sentry configured will either produce build errors or run silently without error tracking active. The README gives no documented method to remove or replace it. For teams with organizational policies against certain third-party services, or that use a different error-tracking stack, the absence of an opt-out path is a concrete constraint worth evaluating before adopting the template.

Sentry's presence in the Sponsors section, alongside BrowserStack, explains the architectural decision. It is wired in as a first-class integration rather than offered as an optional plugin. Teams that already run Sentry will find this removes the setup step entirely. Teams that do not will find themselves adding a Sentry account to the adoption checklist.

WebP conversion, lazy loading and the Atom feed are all produced at build time

All image processing resolves during `astro build`. Images convert to WebP format at that stage, and the `decoding="async"` and `loading="lazy"` attributes appear statically in the generated HTML. Browsers receive pre-converted assets with correct attributes present from the first byte of the page, without performing any transformation or attribute injection on load.

An Atom feed generates automatically alongside `sitemap.xml` and `robots.txt`, with all three appearing at predictable root-level paths after a build. No additional plugin configuration is required beyond what the template already includes in astro.config.ts. This is one of the clearest examples of the architectural stance lumen takes: features that could be opt-in are instead pre-configured.

Sass at version 1.75.0 with PostCSS autoprefixer at 8.5.28 handles CSS, both present in devDependencies alongside TypeScript 5.9.3. A `satori` entry at a semver range in devDependencies is a library commonly associated with generating images from HTML and CSS, which points to social preview image generation as another build-time step. None of these steps require a server-side rendering process after deployment, so the built output is a directory of static files with no runtime dependency on any Node.js or Bun process.

Starting from Astro's own scaffold is the main alternative, with a substantial feature gap

The main alternative to lumen is building an Astro blog from scratch using Astro's own project scaffold, which produces a minimal starting point: pages, components and basic routing, without any opinion on structured data, error tracking, AI indexing or image formats.

Lumen adds a connected JSON-LD graph, Sentry integration, `llms.txt` and `llms-full.txt` endpoints, Markdown source URLs, WebP conversion, Atom feed, semantic HTML with enforced heading nesting, explicit canonical URLs, `sitemap.xml` and `robots.txt`. Each of those requires a separate configuration decision and integration when starting from Astro's own scaffold, and the choices interact: the JSON-LD graph depends on canonical URL structure, which depends on URL configuration, which depends on how the template routes content.

The trade-off is that adopting lumen means accepting its version of each feature as a bundle. If any one piece conflicts with an existing requirement, adjusting it requires understanding the full template before modifying it. The `astro.config.ts` and `astro.config.test.ts` files at the repository root are the starting point for configuration changes, and both carry all of the build-time integrations.

Version 3.0.9 and the semantic-release workflow behind the versioning

The version in package.json is 3.0.9. The repository lists no GitHub releases, but a `.releaserc` file at the repository root and `semantic-release` in devDependencies explain that absence: semantic-release creates tags and changelogs automatically from commit messages following the Conventional Commits convention, producing version tags without requiring manually published GitHub releases.

For contributors, the commit message format determines whether a push produces a patch, a minor or a major version bump, with `semantic-release` at version 25.0.9 in devDependencies driving the process. The `@semantic-release/git` and `@semantic-release/exec` packages handle the Git operations and any custom steps the `.releaserc` defines. An `up-version.mjs` script in `internal/` appears to be a companion script for synchronizing version references across the project, separate from the release workflow itself.

The last push to the repository was on 2026-09-23, and it is not archived. The MIT licence is confirmed by the LICENSE file at the repository root. For a blog template used as the starting point for a public site, MIT imposes no restrictions on how the generated content is published.

Editorial conclusion

Use lumen if you want an Astro static blog with pre-configured JSON-LD forming a connected graph, llms.txt generation and zero client JavaScript, and your team already uses Sentry. Skip it if Sentry is not acceptable as a direct dependency, because the README gives no documented removal path. It also requires Bun rather than Node.js, so any CI pipeline or hosting environment that expects npm will need adjustment. Before publishing, verify the audit script at internal/testing/audit.ts passes, since that is how the project checks JSON-LD consistency between the graph and visible page content.

Frequently asked questions

What is lumen?

Lumen is an Astro static blog template at version 3.0.9 that generates plain HTML at build time with zero client JavaScript by default. It pre-configures JSON-LD structured data as a connected graph, an llms.txt endpoint for LLM indexing, automatic WebP image conversion and an Atom feed.

How do I start a blog with lumen?

Clone the repository, run `bun install` to install dependencies, then `bun run start` to launch the Astro development server. The `content/` directory at the repository root holds the blog posts to modify.

Does lumen require Bun or can I use Node.js?

Bun is the required runtime. The repository uses a `bun.lock` file and the README's quick start commands use `bun install` and `bun run start`. Node.js is not documented as an alternative.

What structured data does lumen generate?

It generates a connected JSON-LD graph with five node types: WebSite, Blog, BlogPosting, WebPage and Person. Each node has a stable ID using a canonical URL with a hash fragment such as `#web` or `#article`, designed to remain consistent across builds.

Is Sentry required to use lumen?

@sentry/astro at version 10.75.0 is listed as a direct dependency in package.json alongside Astro itself, not as a dev dependency. The README documents no method to remove or replace it.

Official sources

  1. alxshelepenok/lumen on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alxshelepenok-lumen.svg)](https://hysenlabs.com/projects/alxshelepenok-lumen)