Tawny

Live design demo

Dev

A minimal mono developer blog with MDX essays and interactive CS demos — open the live showcase. Navigate inside the frame — you are still on Tawny.

designs/dev

DOM

The DOM is one of those things you use every day as a frontend developer without ever quite stopping to think about what it actually is. You call document.querySelector, you add event listeners, you update innerHTML — and it all just works. But when something breaks, or you need to reason about performance, you discover that the DOM has a lot of rules running underneath everything you do.

What Is the DOM?

When a browser parses an HTML document it does not store it as a string. Instead it builds a live tree of objects in memory — the Document Object Model. Every element, every text node, every comment becomes a node in that tree, and JavaScript can read and modify that tree at any time.

The critical word is live. Change the tree from JavaScript and the browser re-renders the affected parts of the page immediately.

dom tree explorer

selected node

p.intro "Introduction."

nodeType: 1

children: 0

Node Types

Not everything in the DOM is an element. Every node has a nodeType integer:

nodeTypeConstantWhat it is
1ELEMENT_NODEAn HTML element
3TEXT_NODEA text run between tags
8COMMENT_NODEAn HTML comment
9DOCUMENT_NODEThe root document object
document.nodeType          // 9 — the document itself
document.body.nodeType     // 1 — an element

children gives you only element nodes (nodeType 1). childNodes gives you everything — elements, text, comments. Most of the time children is what you want.

Selecting Elements

const el = document.querySelector('.card')
const all = document.querySelectorAll('article h2')

Both accept any valid CSS selector. querySelectorAll returns a static NodeList — a snapshot taken at call time.

Event Propagation

When you click a button inside a div, the browser sends the event on a journey through the entire tree. Understanding this journey explains a huge class of bugs and makes event delegation possible.

outer div

middle div

event log

click any element above

Because events bubble, you can attach one listener to a parent and check event.target to know which child was acted on — event delegation.

A Mental Model for the DOM

ConceptKey fact
Node treedocument is the root; everything is a node with nodeType
QueryingquerySelector / querySelectorAll accept any CSS selector
EventsDefault phase is bubbling (target → ancestors)
DelegationOne parent listener beats many child listeners

When the browser behaves unexpectedly, the first question is usually: which node owns this behaviour, and what does the DOM's model say should happen here?

About

Dev is a minimal mono developer blog focused on readable essays and interactive demos. It uses MDX for content, Shiki for syntax highlighting, and a tight typographic system inspired by classic engineer personal sites.

Navigate the live demo above to read sample posts and try the demos. Scaffold your own copy with the create command below, then swap in your name, social links, and writing.

Get the template

Scaffold a local copy with your preferred package manager.

Terminal
pnpm create tawny@latest dev my-app

Template source

Browse every file in templates/dev.

templates/dev

README.md
# Dev Blog

A minimal mono developer blog template — MDX essays, projects, and interactive demos.

Design by [Hugo Lin](https://1chooo.com).

## Quick start

### Option A — create-next-app (recommended)

```bash
npx create-next-app@latest my-blog \
  --example "https://github.com/1chooo/tawny" \
  --example-path "templates/dev"
```

### Option B — create-tawny CLI (interactive prompts)

```bash
npx create-tawny@latest dev my-blog
```

Then:

```bash
cd my-blog
pnpm install   # or npm / yarn / bun
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000).

## Customize these files

| File | What to change |
|------|----------------|
| `app/layout.tsx` | Site title and metadata |
| `app/page.tsx` | About / home copy |
| `components/site-header.tsx` | Brand name in the header |
| `components/site-footer.tsx` | Social links and location |
| `app/blog/_articles/` | Your essays (`.mdx` files) |
| `app/projects/page.mdx` | Projects page |

### Placeholders

Search for `{{AUTHOR_NAME}}`, `{{AUTHOR_EMAIL}}`, `{{GITHUB_USERNAME}}`, and `{{CITY_NAME}}` across the project and replace them.

## Stack

- Next.js 16 App Router & React Server Components
- MDX & Shiki for content
- Tailwind CSS v4
- Minimal mono typography

## License

MIT