Fullstack Example

Learn from a complete production-ready Inertia application.

Litestar Fullstack Inertia

The litestar-fullstack-inertia project is the official reference implementation for building Inertia applications with Litestar.

Tip

This template demonstrates best practices for production applications. Use it as a starting point for your own projects.

Getting Started

# Clone the template
git clone https://github.com/litestar-org/litestar-fullstack-inertia.git
cd litestar-fullstack-inertia

# Install dependencies
make install

# Run development server
make run

Project Structure

litestar-fullstack-inertia/
├── src/
│   └── app/
│       ├── domain/           # Business logic
│       │   ├── accounts/     # User accounts
│       │   ├── teams/        # Team management
│       │   └── system/       # System utilities
│       ├── server/           # Litestar server
│       │   ├── plugins.py    # Plugin configuration
│       │   └── routes.py     # Route registration
│       └── lib/              # Shared utilities
├── resources/                # Frontend assets
│   ├── main.ts               # Entry point
│   ├── pages/                # Inertia page components
│   └── components/           # Reusable components
└── templates/
    └── index.html            # Root template

Key Features

Authentication

  • Session-based authentication

  • Login, logout, registration flows

  • Password reset functionality

  • auth shared prop pattern

Team Management

  • Multi-tenant team support

  • Team invitation system

  • Role-based permissions

Type Safety

  • Full TypeScript support

  • Generated route types

  • Generated page prop types

  • Extended SharedProps

Best Practices

Component kwarg pattern:

# Preferred - clean and declarative
@get("/", component="Home")
async def home() -> dict:
    return {"message": "Hello"}

# Instead of
@get("/")
async def home() -> InertiaResponse:
    return InertiaResponse(component="Home", props={"message": "Hello"})

Guard-based sharing:

async def auth_guard(connection: ASGIConnection, _: BaseRouteHandler) -> None:
    share(connection, "auth", {
        "isAuthenticated": bool(connection.user),
        "user": serialize_user(connection.user),
    })

Type extension:

declare module "litestar-vite-plugin/inertia" {
  interface User {
    avatarUrl?: string;
    teams: Team[];
  }
  interface SharedProps {
    auth: AuthData;
    currentTeam?: Team;
  }
}

Layout pattern:

// pages/Dashboard.tsx
import Layout from "@/layouts/AppLayout";

Dashboard.layout = (page) => <Layout>{page}</Layout>;

export default function Dashboard({ stats }: Props) {
  return <DashboardContent stats={stats} />;
}

See Also