How I Made My Website

11/21/2023 (Updated: 11/25/2023)


Frameworks and Tools


This site is built on SvelteKit (^1.24.1). The main reasons I chose this framework are as follows:

  • Adapters: SvelteKit adapters allow for easy integration with many different hosting platforms (including multiple forms of self-hosting) via adapters. This makes the site agnostic to hosting service, but still plug and play with existing solutions like Cloudflare Pages (the current hosting service as of writing)
  • SSR and Prerendering: Many different frameworks support this, but SvelteKit has first class support for both SSR (export const ssr = true;), and prerendering (export const prerender = true;). These features allow the site to be compiled into pure HTML and CSS wherever possible, speeding up page delivery and reducing redundant computation
  • Optional Hydration: SvelteKit makes it easy to completely disable the JS runtime (export const prerender = false;)


I chose to use tailwindcss (^3.3.3) for styling on this site, as the localized styling as well as robust documentation and ecosystem made it a breeze to use.

When setting up the articles portion of this site, I also added @tailwindcss/typography (^0.5.10) to get access to the .prose which provides the majority of the styling for the very page you are looking at.


Another key tool is mdsvex (^0.11.0), a tool for generating HTML from markdown files, but with the ability to embed not only HTML but also svelte components. The flexibility this grants ensured that anything I could do with a normal svelte file was possible using the markdown files used to layout these pages.

Remark and Rehype

Using MDSveX also opened up a huge ecosystem of remark and rehype plugins, which allow complex transformations of the AST at both the markdown stage and the HTML stage of the transformation. The plugins used include the following:

  • remark-math and rehype-katex: This combination of plugins allows for beautiful and easy math equations embedded right in the markdown. This plays nicely with markdown editors like obsidian, making editing more ergonomic.
  • rehype-toc: Along rehype-autolink-headings and rehype-slug, this plugin provides a very elegant way of creating a table of contents for the site.

Code Highlighting

While there are robust rehype based highlighting plugins, there are often issues using them with MDSveX, due to the way certain symbols which are used in svelte source code are encoded. As such I went with @bitmachina/highlighter (1.0.0-alpha.7), a plugin which is intended for use with MDSveX, and thus has no such issues. Under the hood, it uses shiki, which itself uses the same tokenization engine as VSCode.

Cloudflare Pages

Currently, the site is hosted on Cloudflare using Cloudflare Pages. There are some nice advantages:

  • Cloudflare pages support serverless functions, which pair nicely with +server.ts routes in SvelteKit
  • Continuous deployment is free and plentiful (500 per month on the free plan) and updates are extremely fast
  • Integration with SvelteKit is completely automatic using the preinstalled adapter-auto
  • Setting up multiple domains was easy, and I was already using Cloudflare to manage the relevant DNS
  • Active community


If you like to check out the source code for any of the following examples you can find it here.


Inline Math

Let f(x)=1f(x) = 1. x,yZ\forall x,y \in \Bbb{Z}, x+y=i=1x+yf(i)sin2(i)+cos2(i)x + y = \sum_{i = 1}^{x+y} \frac{f(i)}{\sin^2(i) +\cos ^{2}(i) }.

Math Blocks

a(a2)=b3a(b2)=b3(ab2)b2=(bb2)b2a(b2b2)=b(b2b2)a=b\begin{aligned} a(a^2) &= b^3 \\ a(b^2) &= b^3 \\ (ab^2)b^{-2} &= (bb^2)b^{-2} \\ a(b^2b^{-2}) &= b(b^2b^{-2}) \\ a &= b \end{aligned}


Basic Block

<script lang="ts">let data;

Title and Highlighting

import projects from '$lib/projects';

Highlighting and Line numbers

async function getProjects() {
	return projects;

export async function GET() {
	const projects = await getProjects();
	return json(projects);


Tables Second Row Still Going
col 3 is aligned right $1600