Building a Full-Stack Application

Ready to level up? This guide will show you how to build a complete full-stack application with Alepha, featuring server-side rendering (SSR), client-side navigation, and type-safe routing.

We'll transform a basic server into a modern web application with React components and dynamic pages.

Prerequisites

Make sure you've completed the Getting Started guide first. You'll need:

  • Node.js 22+ or the latest version of Bun
  • A basic Alepha server from the previous guide

1. Install Additional Dependencies

We need to add React and the Alepha React package for full-stack functionality.

npm install react
npm install -D @types/react @vitejs/plugin-react vite

2. Project Structure

Let's organize our project with the following structure:

my-app/
├── src/
│   ├── components/
│   │   ├── Layout.tsx
│   │   ├── Home.tsx
│   │   └── About.tsx
│   ├── styles.css
│   ├── AppRouter.ts
│   ├── index.server.ts
│   └── index.browser.ts
├── index.html
├── vite.config.ts
├── package.json
└── tsconfig.json

3. Create the App Router

The AppRouter is the heart of your full-stack application. It defines all your pages using $page descriptors and handles routing, data fetching, and error handling.

src/AppRouter.ts

import { $page } from "alepha/react";
import { t } from "alepha";

export class AppRouter {
  // Root layout page that wraps all other pages
  layout = $page({
    lazy: () => import("./components/Layout.tsx"),
    children: () => [this.home, this.about],
  });

  // Home page with static generation for performance
  home = $page({
    path: "/",
    static: true,
    lazy: () => import("./components/Home.tsx"),
    resolve: async () => {
      // Fetch data on the server before rendering
      const message = "Welcome to your full-stack Alepha app!";
      const timestamp = new Date().toISOString();

      return {
        message,
        timestamp,
      };
    },
  });

  about = $page({
    path: "/about",
    lazy: () => import("./components/About.tsx")
  });
}

4. Create React Components

Let's create clean React components with simple CSS styling.

src/components/Layout.tsx

import { Link, NestedView, useRouterEvents } from "alepha/react";
import { useState } from "react";

const Layout = () => {
  return (
    <div className="app">
      <header>
        <h1>My Alepha App</h1>
        <nav>
          <Link href="/">Home</Link>
          <Link href="/about">About</Link>
        </nav>
      </header>
      <main>
        <NestedView />
      </main>
    </div>
  );
};

export default Layout;

src/components/Home.tsx

import { Link } from "alepha/react";

interface HomeProps {
  message: string;
  timestamp: string;
}

const Home = ({message, timestamp}: HomeProps) => (
  <div>
    <h1>Full-Stack Alepha Application</h1>
    <p>{message}</p>
    <p>Rendered at: {timestamp}</p>

    <h2>Features</h2>
    <ul>
      <li>Server-Side Rendering (SSR)</li>
      <li>Type-safe routing with $page descriptors</li>
      <li>Automatic code splitting</li>
      <li>Data fetching with resolve functions</li>
      <li>Static generation for performance</li>
    </ul>
  </div>
);

export default Home

src/components/About.tsx

import { Link } from "alepha/react";

const About = () => (
  <div>
    <h1>About Our Application</h1>
  </div>
);

export default About

5. Create Simple Styles

src/styles.css

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  margin: 0;
  padding: 20px;
  line-height: 1.6;
}

header {
  background: #f5f5f5;
  padding: 1rem;
  margin-bottom: 2rem;
  border-radius: 8px;
}

nav a {
  color: #0066cc;
  text-decoration: none;
  margin-right: 1rem;
}

nav a:hover {
  text-decoration: underline;
}

footer {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid #eee;
  color: #666;
}

.loading {
  background: #0066cc;
  color: white;
  padding: 0.5rem;
  border-radius: 4px;
  margin-bottom: 1rem;
}

code {
  background: #f5f5f5;
  padding: 0.25rem 0.5rem;
  border-radius: 3px;
  font-family: monospace;
}

6. Create HTML Template

The HTML template serves as the entry point and includes our CSS file.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Full-Stack App</title>
  <link href="/src/styles.css" rel="stylesheet">
</head>
<body>
  <script type="module" src="/src/index.browser.ts"></script>
</body>
</html>

7. Create Server Entry Point

The server entry point initializes your Alepha application and starts the HTTP server.

src/index.server.ts

import { Alepha, run } from "alepha";
import { AppRouter } from "./AppRouter.ts";

const alepha = Alepha.create();

alepha.with(AppRouter);

run(alepha);

8. Create Browser Entry Point

The browser entry point handles client-side hydration and navigation.

src/index.browser.ts

import { Alepha, run } from "alepha";
import { AppRouter } from "./AppRouter.ts";

const alepha = Alepha.create();

alepha.with(AppRouter);

run(alepha);

9. Configure Vite

Vite handles the build process and development server for your full-stack application.

vite.config.ts

import { viteAlepha } from "alepha/vite";
import viteReact from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    viteReact(),
    viteAlepha({
      // Point to your server entry file
      serverEntry: "./src/index.server.ts",
    }),
  ],
});

10. Update Package.json

Add the necessary scripts and update your package.json:

package.json

{
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}

11. Run Your Full-Stack Application

Now you can run your application in development mode:

npm run dev

Visit http://localhost:5173 in your browser. You'll see:

  • Server-Side Rendering: The page loads instantly with pre-rendered HTML
  • Client-Side Navigation: Smooth navigation between pages without full page reloads
  • Type Safety: Full TypeScript support throughout your application
  • Data Fetching: Server-side data loading with automatic serialization

12. Build for Production

When you're ready to deploy, build your application:

npm run build

This creates:

  • Optimized client-side bundles in dist/client/
  • Server-side code in dist/server/
  • Static assets with proper caching headers

What You've Built

Congratulations! 🎉 You've created a complete full-stack application with:

  • Type-Safe Routing: Using $page descriptors for all routes
  • Server-Side Rendering: Fast initial page loads with SEO benefits
  • Client-Side Navigation: Smooth single-page app experience
  • Data Fetching: Server-side data loading with automatic hydration
  • Static Generation: Performance optimization for static content
  • Development Tools: Hot module replacement and TypeScript support

Next Steps

From here, you can:

  • Add more complex pages with nested routing
  • Integrate databases with alepha/postgres
  • Add email functionality with alepha/email
  • Implement background jobs with alepha/queue
  • Add authentication with alepha/security
  • Deploy to production platforms like Vercel or Railway

Your full-stack Alepha application is now ready for real-world development!

Table of contents

\n\n\n```\n\n### 7. Create Server Entry Point\n\nThe server entry point initializes your Alepha application and starts the HTTP server.\n\n**`src/index.server.ts`**\n```typescript\nimport { Alepha, run } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(AppRouter);\n\nrun(alepha);\n```\n\n### 8. Create Browser Entry Point\n\nThe browser entry point handles client-side hydration and navigation.\n\n**`src/index.browser.ts`**\n```typescript\nimport { Alepha, run } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(AppRouter);\n\nrun(alepha);\n```\n\n### 9. Configure Vite\n\nVite handles the build process and development server for your full-stack application.\n\n**`vite.config.ts`**\n```typescript\nimport { viteAlepha } from \"alepha/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n plugins: [\n viteReact(),\n viteAlepha({\n // Point to your server entry file\n serverEntry: \"./src/index.server.ts\",\n }),\n ],\n});\n```\n\n### 10. Update Package.json\n\nAdd the necessary scripts and update your package.json:\n\n**`package.json`**\n```json\n{\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\"\n }\n}\n```\n\n### 11. Run Your Full-Stack Application\n\nNow you can run your application in development mode:\n\n```bash\nnpm run dev\n```\n\nVisit `http://localhost:5173` in your browser. You'll see:\n\n- **Server-Side Rendering**: The page loads instantly with pre-rendered HTML\n- **Client-Side Navigation**: Smooth navigation between pages without full page reloads\n- **Type Safety**: Full TypeScript support throughout your application\n- **Data Fetching**: Server-side data loading with automatic serialization\n\n### 12. Build for Production\n\nWhen you're ready to deploy, build your application:\n\n```bash\nnpm run build\n```\n\nThis creates:\n- Optimized client-side bundles in `dist/client/`\n- Server-side code in `dist/server/`\n- Static assets with proper caching headers\n\n### What You've Built\n\nCongratulations! 🎉 You've created a complete full-stack application with:\n\n- **Type-Safe Routing**: Using `$page` descriptors for all routes\n- **Server-Side Rendering**: Fast initial page loads with SEO benefits\n- **Client-Side Navigation**: Smooth single-page app experience\n- **Data Fetching**: Server-side data loading with automatic hydration\n- **Static Generation**: Performance optimization for static content\n- **Development Tools**: Hot module replacement and TypeScript support\n\n### Next Steps\n\nFrom here, you can:\n\n- Add more complex pages with nested routing\n- Integrate databases with `alepha/postgres`\n- Add email functionality with `alepha/email`\n- Implement background jobs with `alepha/queue`\n- Add authentication with `alepha/security`\n- Deploy to production platforms like Vercel or Railway\n\nYour full-stack Alepha application is now ready for real-world development!\n","originalName":"3-fullstack-app.md","description":"","path":"apps/docs/assets/guides/3-fullstack-app.md","category":"guides"},"part":"/docs/:slug","config":{"query":{},"params":{"slug":"fullstack-app"}}}]}