Python is finally Reactive.

The High-Performance framework for Python. Combine the raw speed of FastAPI with the power of a Hybrid Engine.

Native Async Type-Safe RPC Hybrid Engine
$ npx create-caspian-app@latest
app/todos/index.html
<!-- 1. Import Python Components -->
<!-- @import { Badge } from ../components/ui -->

<div class="flex gap-2 mb-4">
  <Badge variant="default">Tasks: {todos.length}</Badge>
</div>

<!-- 2. Reactive Loop -->
<ul>
  <template pp-for="todo in todos">
    <li key="{todo.id}" class="p-2 border-b">{todo.title}</li>
  </template>
</ul>

<script>
  // 3. State initialized by Python backend automatically
  const [todos, setTodos] = pp.state([[todos|json]]);
</script>

Why Developers Choose Caspian

We removed the complexity of the modern stack (Node, Webpack, API Routes) but kept the power by building on FastAPI.

FastAPI Engine

Logic runs in native Async Python. Leverage the entire FastAPI ecosystem: Dependency Injection, Pydantic validation, and Starlette middleware. No JavaScript backend required.

TS SUPPORT

Vite + NPM Ecosystem

Need complex libraries? We seamlessly integrate Vite. Import from NPM, write TypeScript, and bundle automatically.

import { motion } from "framer-motion";
// Full Type Safety enabled

File-System Routing

Just create app/users/index.py. We handle the mount points automatically.

Prisma ORM Integration

Define your schema once. Get auto-generated, type-safe Python clients. Zero SQL boilerplate.

model
User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  posts Post[]
}

1,500+ Icons.
One import away.

Don't waste time hunting for SVGs. We integrated ppicons (based on Lucide) directly into the framework. Auto-completion, tree-shaking, and zero configuration.

Terminal
npx ppicons add Rocket
✔ Rocket → src/lib/ppicons/Rocket.py
<!-- Use them instantly in HTML -->
<!-- @import { Rocket, Zap, Github } from ../lib/ppicons -->

<Rocket class="w-6 h-6 text-primary" />
Rocket
Zap
Github
Layout
Data
Code
Cpu
Chat
+1.5k
UI Library

Maddex UI.
Copy. Paste. Ship.

Beautifully designed components that you can copy and paste into your apps. Accessible, type-safe, and built in native Python. No installation fatigue.

Terminal
npx maddex add Button Accordion
✔ Button → src/lib/maddex/Button.py ✔ Accordion → src/lib/maddex/Accordion.py
src/lib/maddex/Button.py
from casp.components import component
from casp.utils import cn

@component
def Button(
    variant="default", 
    size="default", 
    **props
):
    """
    Standard button component with variant support.
    """
    classes = cn(
      "inline-flex items-center justify-center rounded-md",
      "text-sm font-medium transition-colors",
      "focus-visible:outline-none disabled:opacity-50",
      {
        "bg-primary text-primary-foreground hover:bg-primary/90": variant == "default",
        "bg-destructive text-destructive-foreground": variant == "destructive",
        "h-10 px-4 py-2": size == "default",
      }
    )

    return f'<button class="{classes}" {...props} />'
Live Preview

The "Right Tool" Philosophy

We don't force you to write HTML inside Python strings for everything. Use Python Components for atomic, reusable logic. Use HTML Files for complex layouts.

components/Rocket.py
from casp.html_attrs import get_attributes, merge_classes
from casp.component_decorator import component

@component
def Rocket(**props):
    # 1. Handle Tailwind Merging
    incoming_class = props.get("class", " ")
    final_class = merge_classes("w-6 h-6", incoming_class)
    
    # 2. Process Attributes (onclick, id, etc.)
    attributes = get_attributes({
        "class": final_class
    }, props)

    # 3. Return Pure HTML String
    return f'''
      <svg xmlns="http://www.w3.org/2000/svg" 
           viewBox="0 0 24 24" 
           fill="none" 
           stroke="currentColor" 
           {attributes}>
         <path d="M4.5 16.5c-1.5..."></path>
         <path d="m12 15-3-3..."></path>
      </svg>'''

Atomic Components

Perfect for Icons, Buttons, and Badges. merge_classes ensures your Tailwind classes never conflict, and get_attributes automatically handles prop spreading.

Complex Layouts

Don't get stuck in "String Hell". For complex UI like Dashboards or Cards, just point your component to an HTML file.

return render_html("card.html", props)
Live Usage
<Rocket class="text-red-500 animate-bounce" />
Architecture

Direct Async RPC.
No API Routes.

Call Python functions directly from your HTML events. Caspian handles the serialization, security, and async execution transparently.

Type-Safe Arguments
Async Server Execution
actions.py (Backend)
@rpc(require_auth=True)
async def like_post(post_id: str):
    # 1. Direct Prisma DB Access (Async)
    post = await prisma.post.update(
        where={'id': post_id},
        data={'likes': {'increment': 1}}
    )
    # 2. Return data directly to frontend
    return post.likes
index.html (Frontend)
<button 
  onclick="likePost()"
>
  Like Post
</button>

<script>
  async function likePost() {
    // 3. Magic RPC call (over Websocket/HTTP)
    const newCount = await pp.rpc("like_post", { 
      post_id: "123" 
    });
    
    // 4. Update reactive state
    setLikes(newCount);
  }
</script>