Personal portfolio website for Mitchell Jeffrey — science communicator and software engineer based in Cairns, Australia. Live at hello-mlj.net.
A static site built with Nunjucks templates, compiled to plain HTML under docs/ and served via GitHub Pages.
Projects (8 interactive/educational science programs):
- Sound Show, Foldable Flight, Magnets, Security, Market, Mushroom, Election campaign (2022), Radio
Writing (5 published articles):
- Wonky Holes, Lightship Basket Weaving, Psychedelic Psychotherapy, Queer Nuns, Guinea Worm
src/ # Nunjucks templates (.njk)
base.njk # HTML base layout
index.njk # Homepage
projects/ # One template per project
writing/ # One template per article
docs/ # Generated static HTML (committed, served by GitHub Pages)
css/ # Compiled CSS
img/ # Images
audio/ # Audio files
content/ # PDFs (resume, papers)
style.scss # SCSS stylesheet (uses Pico CSS framework)
render.js # Build script — renders all templates to docs/
Install dependencies (includes Sass — no separate Homebrew install needed):
npm installWatch mode + local server (recommended during development):
npm run devThis builds once, then watches .njk and .scss files for changes and serves the site at http://localhost:8000.
One-off build:
npm run buildIndividual commands:
npm run build:css # compile SCSS → docs/css/style.css
npm run build:html # render templates → docs/**/*.html
npm run serve # serve docs/ at localhost:8000The site is hosted on GitHub Pages from the docs/ folder on main.
To deploy:
npm run build— regenerates all HTML and CSS intodocs/- Commit the changes (including
docs/) git push origin main— GitHub Pages picks up the update automatically
The custom domain (hello-mlj.net) is configured via the CNAME file.
| Tool | Purpose |
|---|---|
| Nunjucks 3.2.4 | Template engine |
| Pico CSS v2 | CSS framework |
| Sass | SCSS compilation |
| concurrently | Parallel watch tasks in dev |
| GitHub Pages | Hosting (docs/ on main) |
To add a new page:
- Create a template in
src/projects/orsrc/writing/ - Add a
renderProject('projects/yourpage')call inrender.js - Run
npm run buildto generate the HTML