Your First App
Your First Dex App
In this tutorial, you'll build a simple blog with Dex. You'll learn how pages, layouts, and routing work together.
Prerequisites
- Bun installed (check with
bun --version) - Dex CLI installed or accessible via Bun
- A code editor (VS Code recommended)
Step 1: Create the Project
Scaffold a new Dex application with dex scaffold:
# Scaffold a new Dex project
dex scaffold my-blog
# Enter the project directory
cd my-blogDuring scaffolding, select your project type (spa or mpa). The CLI creates the project structure, downloads required framework packages into packages/, creates .dex/metadata.json, and installs dependencies:
my-blog/
├─ .dex/
│ └─ metadata.json # Template metadata & version tracking
├─ dex.config.ts # Framework configuration
├─ package.json # Dependencies and scripts
├─ tsconfig.json # TypeScript configuration
├─ packages/ # Framework packages (router, server, dev, pie)
├─ web/
│ ├─ pages/ # Your routes go here
│ ├─ layouts/ # Shared layouts
│ └─ public/ # Static assets
└─ routes/ # API route handlersStep 2: Start the Dev Server
Start the development server with dex start (or bun run dev):
dex startYou should see:
🚀 Dex dev server running at http://localhost:7990Open your browser to http://localhost:7990 to see the welcome page.
Step 3: Edit the Homepage
Open web/pages/index.tsx in your editor:
export default function Home() {
return (
<div>
<h1>Welcome to My Blog</h1>
<p>A simple blog built with Dex.</p>
</div>
)
}
export const metadata = {
title: "My Blog - Home"
}Save the file. The dev server will hot-reload, and you'll see your changes.
Step 4: Add a Layout
Create web/layouts/global.tsx:
export default function GlobalLayout({ children }: { children: React.ReactNode }) {
return (
<div>
<nav>
<a href="/">Home</a> | <a href="/about">About</a>
</nav>
<main>{children}</main>
</div>
)
}Every page will now be wrapped with this layout.
Step 5: Add an About Page
Create web/pages/about.tsx:
export default function About() {
return (
<div>
<h1>About This Blog</h1>
<p>This is a Dex-powered blog.</p>
</div>
)
}
export const metadata = {
title: "My Blog - About"
}Visit http://localhost:7990/about to see it.
Step 6: Add a Dynamic Route
Create web/pages/posts/[slug].tsx:
import { useParams } from '@dex/router/client'
export default function Post() {
const { slug } = useParams()
return (
<div>
<h1>Post: {slug}</h1>
<p>This is post number {slug}.</p>
</div>
)
}Visit http://localhost:7990/posts/1 or http://localhost:7990/posts/my-first-post.
Step 7: Build for Production
Build the application for production using dex build (or bun run build):
dex buildThis compiles your application and builds your client bundle and server output into build/.
Step 8: Run Production Server
Start the production server using dex start -p (or bun run start):
dex start -pYour app is now running in production mode (NODE_ENV=production) at http://localhost:7990.
What You Learned
- How to scaffold a Dex project with
dex scaffold <dir> - How pages map to file-based routes in
web/pages/ - How layouts wrap pages in
web/layouts/ - How dynamic routes work with parameters like
[slug] - How to build (
dex build) and run in production (dex start -p)
Next Steps
- File-Based Routing — Deep dive into routing patterns
- Pages and Layouts — Layout composition and metadata
- CLI Commands — Explore all Dex CLI commands
- Configuration — Customize folder structure and options