Building a Personal Academic Site with Quarto
Why Setup a Blog?
Academic blogs have become more accessible than ever, and they’re a great way to keep a personal portfolio and record of your work.
I recently migrated to Quarto for this site, and while it took some time to set up and learn, I’m happy I did. Not just because of aesthetics —though the BioPod theme you’re looking at is entirely custom— but in how the whole thing works. Faster builds, cleaner code, and a system that makes sense when you’re already working in R or Python.
This post walks through how I set up The BioPod using Quarto’s website framework and a custom SCSS theme. It’s aimed at anyone who codes enough to use notebooks but isn’t necessarily a web developer, and who wants a professional site without wrestling WordPress into submission.
What Actually Is Quarto?
Quarto is an open-source scientific publishing system. Think of it as Markdown Pro: write content in .qmd files (Quarto Markdown), and it renders to HTML, PDF, Word docs, presentations, or entire websites.
Here’s why it matters for science communication:
It’s built for data science workflows. You can embed R or Python code directly in your documents, execute it during rendering, and include the outputs (plots, tables, analysis results) automatically. Write once, render everywhere.
It’s fast and portable. Static site generation means no database, no server-side processing, just HTML/CSS/JS files that load instantly. Host it on GitHub Pages for free.
It handles citations natively. BibTeX integration, cross-references, figure numbering—all the academic infrastructure without third-party plugins.
It scales from notebooks to books. Same syntax works for Jupyter-style notebooks, scientific papers, presentations, and full websites. Your lab report and your blog post use the same toolchain.
The perks aren’t just in ease of rendering, but also the custom aesthetics you want to add to your site. With Quarto, you can write SCSS that compiles directly to CSS. You control exactly what gets rendered. No mystery CSS from seventeen different plugins competing for specificity. No surprise JavaScript breaking your site after a theme update. Just your code, doing what you told it to.
Finally, because academic work should be reproducible, your entire site is version-controlled plain text files in Quarto. You can see exactly what changed between versions, roll back mistakes, and rebuild the site identically on any machine with Quarto installed.
The Technical Architecture (Brief Version)
Here’s what happens when you build a Quarto site:
Your content (.qmd files)
↓
Quarto processes Markdown + code chunks
↓
Executes R/Python/Julia code (optional)
↓
Applies theme (SCSS → CSS)
↓
Renders to HTML
↓
Static site in _site/ or docs/
Everything from your .qmd source to the final HTML happens in a single render step. The output is pure static files—HTML, CSS, JavaScript, images—that you can host anywhere.
Quarto uses Bootstrap 5 as its base framework, and you extend it with SCSS variables and custom rules. If you want to dig into the details of how SCSS works, custom fonts, and advanced theming, the Quarto theming documentation covers it comprehensively.
The BioPod Theme
The theme you’re looking at was built around a few specific goals:
- Warm, academic aesthetic — softer colours than the usual stark-white-background blog
- Readable code blocks — high contrast, bold text, clear syntax highlighting
- Custom typography — Crimson Text for body, Apricots for display elements
- Flexible page layouts — different background colours for different page types
Here’s the colour palette:
$bg-primary: #e0cdc5; // Warm beige (headers/footers)
$bg-secondary: #d5c3b3; // Light tan (page backgrounds)
$text-heading: #323619; // Dark olive (headings)
$text-body: #000000; // Black (body text)If you want to use the BioPod theme as a starting point, it’s available on GitHub. Please credit the original if you use it, and more importantly, make it your own—tweak the colours, swap the fonts, adjust the spacing. Academic sites should reflect the person behind them.
Setting Up Your Own Quarto Site
Prerequisites
- Quarto installed (works on Windows, Mac, Linux)
- A text editor (VS Code, RStudio, whatever you prefer)
- Git (for version control and GitHub Pages deployment)
- A GitHub account
- Basic familiarity with Markdown
Project Structure
my-blog/
├── _quarto.yml # Site configuration
├── custom-theme.scss # Your theme (optional)
├── index.qmd # Home page
├── about.qmd # About page
├── posts.qmd # Blog listing
├── posts/ # Blog posts directory
│ └── post-name/
│ └── index.qmd
├── images/ # Site-wide images
└── .github/ # GitHub Actions workflows
└── workflows/
└── publish.yml
Step 1: Initialise the Project
# Create project directory
mkdir my-blog
cd my-blog
# Initialise Quarto website
quarto create project website .This generates a basic site structure with _quarto.yml, index.qmd, and about.qmd.
Step 2: Configure _quarto.yml
This file controls your entire site:
project:
type: website
website:
title: "Your Site Name"
navbar:
background: "#e0cdc5"
left:
- text: "HOME"
href: index.qmd
- text: "BLOG"
href: posts.qmd
- text: "ABOUT"
href: about.qmd
format:
html:
theme: default # Or your custom theme
toc: true
toc-location: rightNote: We’re not setting output-dir: docs here because we’ll be using GitHub Actions to build the site automatically.
Step 3: Create Your First Post
Create posts/my-first-post/index.qmd:
---
title: "My First Post"
author: "Your Name"
date: "2025-01-28"
categories: [news, tutorial]
description: "A brief description for the blog listing"
---
## Introduction
Your content here. Write in Markdown, embed code, include images.Step 4: Set Up Blog Listing
Create posts.qmd to display all posts:
---
title: "Blog"
listing:
contents: posts
sort: "date desc"
type: default
categories: true
fields: [date, title, description]
date-format: "DD MMMM YYYY"
---Step 5: Preview Locally
quarto previewThis opens your site in a browser and live-reloads as you make changes.
Deploying to GitHub Pages
There are two ways to deploy a Quarto site to GitHub Pages:
Method 1: Manual Rendering (Simpler, But More Steps)
- Set
output-dir: docsin_quarto.yml - Run
quarto renderlocally - Commit the
docs/folder to git - Configure GitHub Pages to serve from the
docs/folder
Your workflow becomes: Edit → Render → Add → Commit → Push
This is straightforward but means you need to remember to render before every push, and you’re committing generated HTML files to version control.
Method 2: GitHub Actions (Automated)
GitHub Actions builds your site automatically on every push. You only commit your source .qmd files, and GitHub handles the rendering.
Your workflow becomes: Edit → Add → Commit → Push
This is what I use, and it’s what I’ll walk through here. If you prefer the manual method, the Quarto documentation covers it in detail.
Setting Up GitHub Actions Deployment
Step 1: Create the Workflow File
In your project directory, create .github/workflows/publish.yml:
mkdir -p .github/workflows
nano .github/workflows/publish.ymlPaste this workflow configuration:
name: Publish Quarto Site
on:
push:
branches: main
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Quarto
uses: quarto-dev/quarto-actions/setup@v2
- name: Render site
run: quarto render
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./_site
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4What this does:
- Triggers on every push to the
mainbranch - Spins up an Ubuntu virtual machine
- Runs
quarto renderto build your site - Uploads the built site
- Deploys to GitHub Pages
Step 2: Create Your GitHub Repository
- Go to GitHub and create a new repository
- Name it something like
your-blog - Make it Public (required for free GitHub Pages)
- Don’t initialize with README, .gitignore, or license
Step 3: Push Your Code to GitHub
In your project directory:
# Initialize git (if not already done)
git init
# Add all files
git add .
# Commit
git commit -m "Initial commit: Quarto blog with GitHub Actions deployment"
# Link to your GitHub repository
git remote add origin https://github.com/yourusername/your-blog.git
# Push to GitHub
git branch -M main
git push -u origin mainYou’ll need a Personal Access Token (classic) instead of your password for HTTPS authentication.
Step 4: Configure GitHub Pages
- Go to your repository on GitHub
- Settings → Pages
- Under “Build and deployment”:
- Source: GitHub Actions (not “Deploy from a branch”)
- That’s it - no need to select a branch or folder
Step 5: Watch It Build
- Go to the Actions tab in your repository
- You’ll see a workflow run called “Publish Quarto Site”
- After 2-3 minutes, your site will be live at
https://yourusername.github.io/your-blog/
Your Publishing Workflow
From now on, whenever you want to update your blog:
# 1. Edit your .qmd files
# 2. Preview locally to check everything looks right
quarto preview
# 3. Commit and push
git add .
git commit -m "Add new blog post about gene regulatory networks"
git pushThat’s it. GitHub Actions handles the rendering automatically. Within a few minutes, your changes are live.
No need to run quarto render yourself, no need to commit the generated HTML files. Just edit your source files and push.
What You Get
After following this setup, you’ll have:
- A fast, clean static site hosted for free on GitHub Pages
- Automated deployment that rebuilds on every push
- Version-controlled content as plain text files
- Full control over design and functionality via SCSS (if you want it)
- Native support for code execution, citations, and cross-references
- A publishing workflow that integrates with your research tools
It’s not the easiest option - WordPress is still easier if you’ve never touched code. But if you’re already working in R or Python, and you want a professional site that you actually understand and control, Quarto hits a sweet spot.
The initial setup takes an afternoon. After that, writing and publishing a new post takes minutes.