Replace Elysia with bun.serve for hot reloading and static serving
This commit is contained in:
103
content/2025/10/building-with-bun.md
Normal file
103
content/2025/10/building-with-bun.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Building a Modern Blog with Bun and TypeScript
|
||||
date: 2025-10-20
|
||||
tags: [Web Development, TypeScript, JavaScript]
|
||||
excerpt: A deep dive into building a performant, modern blog using Bun's runtime, TypeScript, and server-side rendering. Learn about the architecture decisions and tradeoffs.
|
||||
draft: false
|
||||
---
|
||||
|
||||
# Building a Modern Blog with Bun and TypeScript
|
||||
|
||||
When I set out to build this blog, I had a few key requirements in mind: fast page loads, minimal JavaScript shipped to the client, and a great developer experience. Here's how I achieved all three.
|
||||
|
||||
## Why Bun?
|
||||
|
||||
Bun is an all-in-one JavaScript runtime that's significantly faster than Node.js for many operations. It includes:
|
||||
|
||||
- A blazing-fast JavaScript/TypeScript runtime
|
||||
- Built-in bundler
|
||||
- Native TypeScript support
|
||||
- Package manager
|
||||
- Test runner
|
||||
|
||||
For this blog, the combination of native TypeScript support and the built-in bundler made Bun an obvious choice.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The blog uses a hybrid approach:
|
||||
|
||||
### Server-Side Rendering
|
||||
|
||||
All HTML is generated on the server using JSX as a templating language. This means:
|
||||
|
||||
- **Fast initial page loads** - No waiting for JavaScript to download and execute
|
||||
- **SEO friendly** - Search engines see fully rendered HTML
|
||||
- **Works without JavaScript** - Core functionality doesn't depend on client-side JS
|
||||
|
||||
### AppShell Pattern
|
||||
|
||||
The blog implements an "AppShell" pattern where:
|
||||
|
||||
1. First visit loads the full page with AppShell (sidebar, header, etc.)
|
||||
2. Navigation replaces only the `<main>` content
|
||||
3. Subsequent requests send a custom header to indicate AppShell is already loaded
|
||||
4. Server returns just the content, not the full shell
|
||||
|
||||
This gives us SPA-like navigation speed with SSR benefits.
|
||||
|
||||
## Markdown Processing
|
||||
|
||||
Blog posts are written in Markdown and processed at build time:
|
||||
|
||||
```typescript
|
||||
// Simplified example
|
||||
import { marked } from 'marked';
|
||||
|
||||
const html = marked.parse(markdownContent);
|
||||
```
|
||||
|
||||
The plugin:
|
||||
- Scans the content directory
|
||||
- Parses frontmatter (title, date, tags, etc.)
|
||||
- Converts markdown to HTML
|
||||
- Stores everything in SQLite for fast queries
|
||||
|
||||
## Performance Results
|
||||
|
||||
The result? Page loads under 128KB including:
|
||||
- All HTML
|
||||
- All CSS (inlined)
|
||||
- Minimal JavaScript for interactivity
|
||||
|
||||
First contentful paint happens in under 100ms on a fast connection.
|
||||
|
||||
## Developer Experience
|
||||
|
||||
With Bun's `--watch` flag, the entire development workflow is seamless:
|
||||
|
||||
```bash
|
||||
bun run --watch ./index.tsx
|
||||
```
|
||||
|
||||
This watches for changes and hot-reloads the server. Combined with the markdown plugin, changing a blog post immediately reflects in the browser.
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
### What Worked Well
|
||||
|
||||
- **JSX for templating** - Familiar, type-safe, and no new syntax to learn
|
||||
- **SQLite for search** - Fast, embedded, and perfect for a small blog
|
||||
- **Bun's speed** - Development is incredibly fast
|
||||
|
||||
### What Could Be Better
|
||||
|
||||
- **Hot reloading** - Would love client-side HMR for styles
|
||||
- **Build step** - Currently all processing happens at runtime
|
||||
- **TypeScript types** - Virtual modules need proper type definitions
|
||||
|
||||
## Conclusion
|
||||
|
||||
Building with Bun has been a great experience. The performance is excellent, and the developer experience is top-notch. If you're building a new project and want to try something modern, I highly recommend giving Bun a shot.
|
||||
|
||||
The code for this blog is open source - check it out on GitHub!
|
||||
|
||||
Reference in New Issue
Block a user