A small personal academic website built entirely in Typst,
using its experimental bundle export target to produce a multi-page
static site from a single typst compile invocation.
No JavaScript, Node or Jekyll with their load of bloat and inscrutable layouts: just a minimal amount of simple, clean Typst code.
Also takes most content from a Typst CV repo to minimise maintenance effort.
Visual style is a restrained, serif, tufte-inspired academic look.
typst ≥ 0.15, with the experimentalbundleandhtmlexport features (see Typst's bundle docs). Both are behind feature flags and not stable —expect breakage on future Typst releases.
./build.sh # one-off build into ./dist
./build.sh --watch # live-reloading dev server at http://localhost:3000Equivalent to running directly:
TYPST_FEATURES=bundle,html typst compile --format bundle main.typ distThen serve/upload the contents of dist/ anywhere static files are served
(GitHub Pages, Netlify, S3, ...).
main.typ entry point —one #page(...) call per site page
config.typ your name, bio, avatar, social links, nav — edit this first
lib/
layout.typ shared header/nav/footer page shell
icons.typ inline SVG icons for social links
content/
CV/
CV.pdf
me.bib
teaching.typ
assets/
avatar.png your profile picture (replace this)
favicon.ico
build.sh
-
Home page / bio / socials: edit
config.typ. -
Profile picture: replace
assets/avatar.pngwith your own image (any raster format Typst supports: PNG, JPEG, ...) and updatesite.avatarinconfig.typif you rename it. It's embedded directly into the HTML as a data URI, so there's nothing else to wire up. -
Publications: edit
content/CV/me.bibdirectly. Every entry in the file is rendered, in the citation order determined by thestyle:argument passed tobibliography(...)inmain.typ(currently"apa"; any CSL style name or path works, e.g."ieee"). -
Teaching: each course is a dictionary entry in
content/CV/teaching.typ.
- New page: add another
#page("newpage.html", ...)[ ... ]block tomain.typand an entry innav-itemsinconfig.typ. - New icons: download a pack from https://ecstrema.github.io/iconify-typst/, place the JSON in
assets/and load it inlib/icons.typ. - CV / extra files: use
#asset("cv.pdf", read("content/cv.pdf", encoding: none))inmain.typto copy any file into the bundle verbatim.
- Bundle & HTML export are experimental Typst features; behavior may change across Typst versions.
<style>/<link>tags are currently emitted in<body>rather than<head>, since bundle export doesn't yet hoist elements to<head>. This renders correctly in all modern browsers but isn't strictly spec-compliant.