Quick Start
This guide walks you through creating a Catmint project, starting the development server, and building your first pages with routing and layouts.
1. Create a Project
Scaffold a new project with the create-catmint CLI:
pnpm create catmint my-app
cd my-app
pnpm install
This generates a project with the following structure:
my-app/
app/
page.tsx
layout.tsx
public/
catmint.config.ts
tsconfig.json
package.json
2. Start the Dev Server
Run the development server with hot module replacement:
pnpm dev
Open http://localhost:5173 in your browser. The dev server is powered by Vite and supports fast refresh for both server and client components.
3. Create Your First Page
Pages are React components exported as the default export from page.tsx files inside the app/ directory. Open app/page.tsx and replace its contents:
// app/page.tsx
export default function HomePage() {
return (
<div>
<h1>Welcome to Catmint</h1>
<p>Your full-stack React framework is up and running.</p>
</div>
)
}
Save the file and the browser will update immediately.
4. Add a Route
Catmint uses file-based routing. Create a new directory and page to add a route:
mkdir -p app/about
// app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>About</h1>
<p>This page is served at /about.</p>
</div>
)
}
Navigate to http://localhost:5173/about to see the new page. No configuration or manual route registration is required.
Dynamic routes
Use bracket syntax to create dynamic segments. For example, a blog post page:
mkdir -p app/blog/[slug]
// app/blog/[slug]/page.tsx
import { useParams } from 'catmint/hooks'
export default function BlogPostPage() {
const { slug } = useParams()
return (
<div>
<h1>Blog Post</h1>
<p>You are viewing: {slug}</p>
</div>
)
}
Visiting /blog/hello-world will render with slug set to "hello-world".
5. Add a Layout
Layouts wrap pages and persist across sibling navigation. They are defined by exporting a default component from layout.tsx:
// app/layout.tsx
import React from 'react'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>My Catmint App</title>
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/blog/first-post">Blog</a>
</nav>
<main>{children}</main>
</body>
</html>
)
}
Every page inside app/ will now be wrapped by this layout. You can nest layouts by adding layout.tsx files in subdirectories. Each layout receives its child content via the children prop.
Nested layouts
Add a layout specific to the blog section:
// app/blog/layout.tsx
import React from 'react'
export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div>
<aside>
<h2>Blog Navigation</h2>
<ul>
<li><a href="/blog/first-post">First Post</a></li>
<li><a href="/blog/second-post">Second Post</a></li>
</ul>
</aside>
<article>{children}</article>
</div>
)
}
Pages under app/blog/ will render inside both the root layout and the blog layout. The layout chain is determined by the directory hierarchy.
6. Build and Preview
When you are ready to build for production:
pnpm build
Then start the production server:
pnpm start
The catmint build command compiles your application using Vite, producing optimized server and client bundles. The catmint start command runs the built application using your configured deployment adapter.
CLI Commands
| Command | Description |
|---|---|
catmint dev | Start the development server with HMR |
catmint build | Build for production |
catmint start | Start the production server |
catmint generate | Generate route types and other artifacts |
Next Steps
- Project Structure -- learn about file conventions and directory layout
- Routing -- dynamic segments, catch-all routes, and route groups
- Server Functions -- call server-side code directly from components
- Middleware -- intercept requests with the onion execution model
