Hello, codn — Hit Lighthouse 100 with Almost No JS

6 min read
  • astro
  • performance
  • seo
  • web
  • meta

This is the first post on codn.dev. Rather than write about something abstract, I want to start with how this site works — because the decisions behind it reflect how I think about the web.

I built codn because I wanted one corner of the web to feel simple again. After years of seeing basic pages turn into miniature applications, I wanted a site I could deploy with rsync, inspect with curl, and understand end to end without hand-waving.

The Problem with Modern Websites

Open your browser’s network tab on a typical blog. You will find dozens of requests: analytics, fonts from Google, chat widgets, cookie banners, social embeds, A/B testing scripts. A blog post that is three paragraphs long loading 800 KB of JavaScript.

This is not a performance problem. It is a priorities problem.

A blog has one job: deliver words to a reader, fast and without friction. HTML and CSS are extraordinarily good at this. The web platform is extraordinarily good at this. We have just spent a decade layering abstractions on top of it until the simplest task requires a build pipeline and a consent dialog.

codn.dev is my attempt to go the other direction.

The Stack

The site is built with Astro, deployed as fully static files, and served by Nginx on a VPS in Germany. The content lives in Markdown and MDX files, validated by Astro content collections with Zod schemas. There are zero runtime dependencies — dependencies in package.json is empty.

src/content/posts/*.md(x)


Astro build → static HTML + CSS


rsync → Nginx → you

No Node.js in production. No database. No serverless functions. Just files on a disk.

Almost Zero JavaScript

The entire site ships two tiny interactive scripts: one that powers the copy button on code blocks, and one that copies the current post URL. That is it.

No hydrated islands. No framework components. No Google Tag Manager. Syntax highlighting is done at build time by Shiki with the synthwave-84 theme — the output is static HTML with CSS classes, not a runtime highlighter. The site is dark-only — all color tokens are hardcoded for a dark palette.

When I say almost zero JS, I mean the browser has nothing meaningful to parse, compile, or execute on page load. That is not a technical achievement — it is what happens when you remove things that were never needed.

Fonts: Self-Hosted or Nothing

Every font on this site is hosted on the same server as the HTML. No requests to Google Fonts, no Typekit, no Bunny Fonts. The typefaces — Söhne, Söhne Mono, and MonoLisa — are loaded from public/fonts/ as woff2 files. Body fonts use font-display: swap; code fonts use font-display: optional.

Critical fonts (body text) are preloaded in <head>:

<link rel="preload" href="/fonts/soehne-buch.woff2" as="font" type="font/woff2" crossorigin />

Code fonts are loaded only on post pages, not globally. This keeps the homepage fast even for readers who never open a code block.

The result: typography renders immediately without layout shift, and no third-party server learns your IP address because you visited a blog.

Lighthouse 100

Hitting a perfect Lighthouse score on a static site is not hard if you do not fight the platform. The things that matter:

  • Minimal critical path — small static CSS bundles, preloaded text fonts
  • No external scripts — nothing loads from a CDN at runtime
  • Brotli and gzip compression via Nginx for HTML, CSS, JS, JSON, and SVG
  • Immutable cache headers on fonts (Cache-Control: public, max-age=31536000, immutable)
  • HTTPS redirect from HTTP, HTTP/2 enabled
  • Static 404 — no server-side redirect chain for missing pages

Here is what one Lighthouse run against codn.dev looked like after deployment:

Chrome Lighthouse report for codn.dev showing 100 scores for Performance, Accessibility, Best Practices, and SEO.

A Lighthouse run against codn.dev showing 100 across Performance, Accessibility, Best Practices, and SEO.

Performance is not something you optimize after the fact. It is what remains when you stop adding things that slow the page down.

SEO Without Plugins

Every page on codn.dev emits structured data as JSON-LD, generated at build time by src/utils/seo.ts. Posts get a BlogPosting schema. The homepage gets WebSite. Posts with FAQ sections get FAQPage. There are also canonical URLs, OpenGraph tags, and Twitter Card metadata on every page.

None of this requires a plugin or a third-party service. It is just JSON in a <script type="application/ld+json"> tag, generated from the same frontmatter that populates the page title and description.

The sitemap is generated by @astrojs/sitemap with explicit priority and changefreq values per route — and /llms.txt is included as a custom page so crawlers and AI systems can discover it. The RSS feed covers all posts. The FAQ markup is there because it is valid machine-readable metadata, not because I expect a personal dev blog to suddenly get Google FAQ rich results.

llms.txt — Discoverable by AI

Something less common: the site generates a /llms.txt file at build time. It is a plain-text index of all posts with their URLs and descriptions, followed by links to the RSS feed and sitemap.

The idea is simple. Search crawlers have robots.txt and sitemaps. AI language models increasingly consume plain-text files directly when they index or reason about web content. llms.txt is an emerging convention for making a site’s content legible to those systems. codn.dev adopted it on day one.

What This Site Is For

codn.dev is where I write about software development — specifically the parts that interest me: performance, architecture, developer tooling, and increasingly the intersection of AI and how code gets written.

More posts are coming. If you want them, the RSS feed is at /rss.xml, and if you want the person behind the site, there is an /about/ page too.

Frequently Asked Questions

Q: Why does codn.dev use almost no JavaScript?

A: Because most of what a blog needs — layout, typography, navigation, syntax highlighting — can be done entirely in HTML and CSS. JavaScript adds weight, parsing time, and complexity. The only JS on this site lives in two tiny inline scripts: one for the copy button on code blocks and one for copying the current post URL.

Q: How did codn.dev hit a Lighthouse score of 100?

A: Static output via Astro, self-hosted fonts, no third-party scripts, small CSS, preloaded text fonts, Brotli and gzip compression via Nginx, and immutable cache headers for fonts. Nothing loads from an external CDN.

Q: What is llms.txt and why does codn.dev have one?

A: llms.txt is a plain-text index of a site's content, designed to help AI language models discover and understand what a site contains. codn.dev generates one at build time using Astro.

Q: Is Astro good for a blog?

A: Yes. Astro's static output, content collections, and zero-JS-by-default philosophy make it close to ideal for a content-focused site that needs to be fast and maintainable.