A developer blog built with Next.js 16 and Bun. It prioritizes speed, simplicity, and a clean reading experience.
- Next.js 16 App Router: High performance server components and layouts.
- Markdown Support: Write posts in Markdown with Shiki syntax highlighting.
- Cover Images: Upload or link cover images for posts and projects.
- Project Showcase: Dedicated section for projects with GitHub README auto-import.
- Instant Search: Full-text search powered by PostgreSQL tsvector.
- Complete Auth: Email, password, and GitHub OAuth support via Auth.js v5.
- Admin Dashboard: Secure management of posts, projects, tags, comments, and users.
- Comments: Built-in reply system with XSS protection.
- Notifications: Real-time alerts for user interactions.
- Media Management: Simple image upload system for blog posts and projects.
- SEO Ready: Automated RSS 2.0 feed, dynamic sitemap, Open Graph tags, JSON-LD structured data, and
robots.txt. - Theme Support: Built-in dark and light modes with consistent typography.
- Framework: Next.js 16
- Runtime: Bun
- Styling: Tailwind CSS v4 and shadcn/ui
- Database: PostgreSQL with Drizzle ORM
- Authentication: Auth.js v5
- Icons: Lucide React
- Bun v1.1 or higher
- Node.js v20 or higher
- PostgreSQL 15 or higher
Follow these steps to run the blog on your machine.
-
Clone the repo
git clone https://github.com/chakyiu/chakyiu-blog.git
-
Install dependencies
bun install
-
Set up environment
cp .env.example .env.local
Open
.env.localand add your secrets. -
Prepare the database
bun run migrate
-
Start development
bun run dev
Visit http://localhost:3000 to see it live.
| Name | Description | Required |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string. Example: postgres://postgres:postgres@localhost:5432/blog. |
Yes |
AUTH_SECRET |
Secret key for session security. Generate one using bunx auth secret. |
Yes |
AUTH_GITHUB_ID |
GitHub OAuth client ID. | No |
AUTH_GITHUB_SECRET |
GitHub OAuth client secret. | No |
NEXT_PUBLIC_BASE_URL |
Your site's primary URL for RSS, sitemap, and SEO links. | Yes |
NEXT_PUBLIC_GSC_VERIFICATION |
Google Search Console verification token. See SEO & Google Indexing. | No |
bun run dev: Start the local development server.bun run build: Build the app for production.bun run start: Run the production server.bun run migrate: Run database migrations.bun test: Execute the test suite.
Run the entire stack using Docker Compose.
docker-compose up --buildThis command builds the container and starts the blog with a PostgreSQL database. Data is persisted in a volume called pg_data.
src/app: Page routes and layouts.src/components: UI components and building blocks.src/lib: Database schemas, auth config, and helpers.src/hooks: Custom React hooks.public: Static files and images.
/: Home page with post list/posts/[slug]: Detailed blog post view/projects: Project showcase/projects/[slug]: Detailed project view/search: Site-wide search/feed.xml: RSS 2.0 feed/sitemap.xml: XML sitemap for search engines/robots.txt: Crawler directives/api/health: Health check endpoint
/auth/login: Login page/auth/register: Signup page/notifications: Personal notification feed/history: Comment history/settings: Profile and account settings
/admin: Main dashboard/admin/posts: Post management/admin/projects: Project management/admin/tags: Tag management/admin/comments: Comment moderation/admin/users: User management
The blog includes a full SEO setup out of the box:
robots.txt— served frompublic/robots.txt. Allows all public routes and blocks/admin/,/api/,/auth/. Points crawlers to the sitemap./sitemap.xml— dynamic route (src/app/sitemap.ts) that queries the DB at runtime and lists all published posts and projects. Updates automatically as you publish.- Open Graph & Twitter cards — generated per-page via Next.js metadata API.
- JSON-LD —
BlogPostingstructured data injected on every post page. - RSS feed — available at
/feed.xml.
- Deploy the site so
https://your-domain/sitemap.xmland/robots.txtare publicly accessible. - Go to Google Search Console and add your site as a URL-prefix property.
- Choose the HTML tag verification method and copy the token value.
- Add it to your environment:
NEXT_PUBLIC_GSC_VERIFICATION=your-token-here - Redeploy, then click Verify in Search Console.
- Navigate to Sitemaps and submit
https://your-domain/sitemap.xml. - Use the URL Inspection tool to request indexing for your homepage and key posts.
The token is intentionally kept out of source code. It is public (rendered in HTML) but should not be committed to a public repository.
Pull requests are welcome. For major changes, please open an issue first to discuss what you want to change.