pdx.su

June 15, 2026 · View on GitHub

Personal blog of Jeff Sandberg — software engineer.

https://pdx.su

Stack

LayerTechnology
SSGTableau (Elixir)
TemplatesPhoenix LiveView HEEx
CSSSass (Esbuild via Bun)
JSTypeScript + Lit web components
MarkdownMDEx (CommonMark + extensions)
DjotDjot + Autumn for syntax highlighting
DeploymentGitHub Actions → Netlify
Hookshk

Writing posts

Posts live in _posts/ and are written in either Markdown (.md) or Djot (.dj). Front matter is YAML.

Supported Markdown extensions: alerts, autolink, description lists, footnotes, math, strikethrough, subscript/superscript, tables, task lists, underline.

Djot posts get syntax highlighting via Autumn, with line-level highlight annotations via highlight attributes on code blocks.

Development

Prerequisites

  • Elixir 1.15+
  • Bun (for asset building)

Getting started

mix deps.get
bun install
mix tableau.server

The reloader watches assets/, lib/, _posts/, and _pages/ for changes.

Asset pipeline

Sass compiles to CSS; TypeScript compiles via Esbuild. Both run through Bun.

bun install

The asset watcher starts automatically alongside mix tableau.server (configured in config.exs).

Pre-commit hooks

hk check    # run all checks
hk fix      # auto-fix where possible (formatting)

Checks include: Elixir compilation, formatting, Pkl validation, and Prettier.

Creating posts

mix post.new "Post title"          # defaults to Djot
mix post.new --markdown "Title"    # Markdown
mix post.new --filename my-post "Title"
mix post.new --date 2026-01-01 "Title"

License

Source code: MIT.

Text content (_posts/, _pages/, etc.): Copyright (c) each post's date by Jeff Sandberg.