The website for Fredrik Kjolstad's research group in the Stanford University Department of Computer Science. A fast, accessible, statically-generated site that presents the group's research, people, publications, and software.
The lab's identity — display name, tagline, canonical URL, nav, and more — lives in a single file,
src/config/site.ts. See Renaming the lab.
- What it is: an editorial, research-first lab site with a searchable/filterable publication explorer, a connected software catalogue, a people directory, and a research narrative — built around the theme "computation, re-formed."
- Content model: all content is local, typed, and validated (Astro content collections + Zod). No CMS or database; a CMS can be layered on later without touching presentation.
- Performance: ~5 KB of gzipped JavaScript for the whole site; static HTML for every page.
- Accessibility: targets WCAG 2.2 AA; tested with axe + manual review.
| Area | Choice |
|---|---|
| Framework | Astro 5 (static output), strict TypeScript |
| Styling | Hand-built design system — CSS custom properties + Astro scoped CSS. No UI kit, no Tailwind. |
| Interactivity | Tiny vanilla-TS islands only (publication explorer, theme, nav, clipboard). No React/Vue/etc. |
| Fonts | Self-hosted, Latin-subset WOFF2 (Fraunces, IBM Plex Sans, IBM Plex Mono) |
| Content | Astro content collections: people & software (Markdown), publications (validated YAML) |
| Tests | Vitest (unit), Playwright + axe-core (e2e/a11y) across Chromium, Firefox, WebKit, mobile |
| Tooling | pnpm, ESLint 9, Prettier, astro check |
- Node ≥ 20.11 (
.nvmrcpins 20.11.0) - pnpm (pinned via
packageManagerinpackage.json; runcorepack enable)
corepack enable # makes the pinned pnpm available
pnpm install # installs from the committed lockfilepnpm dev # http://localhost:4321 with hot reloadpnpm run verify # format + lint + content validation + types + unit + build + links
# individually:
pnpm run format:check # Prettier
pnpm run lint # ESLint
pnpm run validate:content# cross-reference integrity (author↔person, pub↔software, …)
pnpm run check # astro check (TypeScript across .astro/.ts)
pnpm run test:unit # Vitest unit tests (filtering, citations, people helpers)
pnpm run build # production build
pnpm run check:links # internal-link checker (runs against dist/)
pnpm run test:e2e:install# one-time: install Playwright browsers
pnpm run test:e2e # Playwright e2e + axe accessibility across all browserspnpm run build # outputs static site to ./distpnpm run preview # serves ./dist at http://localhost:4321The output is a plain static site (dist/). Any static host works.
Netlify / Cloudflare Pages (config already included):
- Build command:
pnpm run build· Publish directory:dist netlify.tomlsets the Node version and base headers.public/_headersships the security headers + a Content-Security-Policy and long-cache rules for hashed assets and fonts.public/_redirectsholds legacy redirects.
GitHub Pages / university static hosting / any bucket: upload the contents of dist/.
On hosts that don't read _headers/_redirects, replicate the headers from public/_headers
in your server/CDN config (they are also mirrored in netlify.toml).
Before the first public deploy, set the real domain in src/config/site.ts (SITE.url) so
canonical URLs, the sitemap, and robots.txt are correct.
All content lives in src/content/. Full instructions — adding a person, moving someone to
alumni, adding a publication or award, adding/updating software, adding a portrait, changing
homepage featured items — are in CONTENT_GUIDE.md. Every change is
schema-validated at build time; run pnpm run validate:content for a fast pre-check.
Edit one file — src/config/site.ts:
export const SITE = {
name: 'Stanford Compilers Lab', // ← the display name
shortName: 'Stanford Compilers Lab', // ← used in the wordmark & nav
tagline: '…',
url: 'https://compilers.stanford.edu', // ← canonical domain
// …
};If the wordmark text in the favicon / social image should also change, re-run
pnpm run generate:assets. Nothing else references the name directly.
Targets WCAG 2.2 AA. Semantic landmarks, a logical heading order, a skip link, visible
focus states, full keyboard operation, prefers-reduced-motion support, AA-contrast light
and dark themes, and a no-JavaScript fallback for the publication list (the complete
grouped list is always present; only live filtering needs JS). Verified with automated
axe-core scans in Playwright plus manual review; see the
testing notes.
Static HTML for every page; no framework runtime. Total JS is ~5 KB gzipped (Astro's
view-transition runtime plus a ~1 KB publication-filter island loaded only on the
publications page). Self-hosted subset fonts with font-display: swap and preloading of the
two critical faces; no third-party requests, analytics, or embeds by default. Lighthouse
(mobile) scores 98–100 across Performance, Accessibility, Best Practices, and SEO.
src/
config/site.ts Single source of truth for lab identity, nav, analytics, flags
content/ Local content (validated by src/content.config.ts)
people/*.md One file per person (bio in body, facts in frontmatter)
software/*.md One file per project (narrative in body, facts in frontmatter)
publications.yaml All publications (one validated entry each)
components/ UI, global, navigation, home, people, publications, software, research
layouts/ BaseLayout (shell + SEO), PageLayout (page header)
lib/ Pure logic: publications (filter/sort/URL), citation, people, taxonomy, collections
pages/ Routes (incl. [slug] detail pages, robots.txt, site.webmanifest)
styles/ Design tokens, base, fonts, print
assets/, public/ Fonts, favicons, OG image
scripts/
import-legacy-content.ts One-time: parse the archived old site → publications.yaml
generate-assets.ts Generate favicons + OG image from the design system
validate-content.ts Cross-reference integrity checker
check-links.ts Internal-link checker (against dist/)
legacy/ Committed archive of the source site + software verification
tests/
unit/ Vitest unit tests
e2e/ Playwright e2e + axe accessibility
ARCHITECTURE.md— how the site is put together and why.DESIGN.md— the design system: type, colour, motifs, theming.CONTENT_GUIDE.md— day-to-day content editing.CONTENT_REVIEW.md— facts & wording awaiting human confirmation.