Skip to main content

Full-stack React + Python with zero configuration. Build modern React apps with FastAPI, Bun, Inertia.js, and Tailwind CSS.

Project description

Vegabase

Full-stack React + Python with zero configuration.

Build modern React applications powered by FastAPI, Bun, Inertia.js, and Tailwind CSS โ€” all from a single pip install.

Motivation

When building React apps with Python, you typically have two choices:

  • SPA-only: An empty HTML shell, React takes over in the browser. No SEO, slow initial loads, and you still need to build a REST/GraphQL API.
  • Jinja + Islands: Server-render with templates, sprinkle React for interactivity. But you're constantly juggling two mental models.

Full-stack JS frameworks like Next and TanStack have SSR, hydration, and flexible rendering modes. Vegabase brings this experience to Python โ€” use Python for backend logic, JavaScript for rendering html.

Features

  • ๐Ÿš€ Zero Config: Just install and run. Handles TS, TSX/JSX, CSS bundling with Tailwind support.
  • ๐Ÿ Python-First: FastAPI backend with Python's full ecosystem.
  • โš›๏ธ Modern React: React 19 with server-side rendering out of the box.
  • โšก Bun-Powered: Lightning-fast bundling and SSR performance.
  • ๐Ÿ—„๏ธ Type-Safe Database: Built-in database module with Pydantic validation.
  • ๐ŸŽจ Flexible Rendering: SSR, client-only, ISR caching, or static HTML per-page.

Requirements:

  • Bun v1.0+ must be installed
  • Python 3.11+

Quick Start

# Create a new project with uvx (no install needed)
uvx vegabase init my-app --example posts

cd my-app
uv sync && bun install

# Terminal 1: Frontend dev server
vegabase dev

# Terminal 2: Backend
APP_ENV=development python -m backend.main

Visit http://localhost:8000 ๐ŸŽ‰

CLI Commands

Command Description
vegabase init Create a new project
vegabase dev Start dev server with hot reloading
vegabase build Build optimized production bundles
vegabase ssr Start the SSR server for production
vegabase db plan Preview database schema changes
vegabase db apply Apply schema changes to database

Init Options

vegabase init --name my-app              # Create empty project
vegabase init --name my-app --example posts  # Start from posts example
vegabase init --name my-app --db sqlite      # Include SQLite setup
vegabase init --name my-app --db postgres    # Include PostgreSQL setup

Rendering Modes

Control how each page is rendered:

from vegabase import Inertia

inertia = Inertia(app)

# Default: Server-side rendering
await inertia.render("Home", props, request, mode="ssr")

# Client-only: Skip SSR, render in browser
await inertia.render("Dashboard", props, request, mode="client")

# Cached (ISR): Cache for 60 seconds
await inertia.render("Posts/Index", props, request, mode="cached", revalidate=60)

# Static: Pure HTML, no JavaScript bundle
await inertia.render("About", props, request, mode="static")
Mode SSR Hydration Use Case
ssr โœ… โœ… Default, SEO-important pages
client โŒ โœ… Dashboards, authenticated pages
cached โœ… โœ… Blog posts, product pages (ISR)
static โœ… โŒ Landing pages, pure content

Flash Messages

Built-in flash message support:

from starlette.middleware.sessions import SessionMiddleware

app.add_middleware(SessionMiddleware, secret_key="...")
inertia = Inertia(app)

@app.post("/posts/create")
async def create_post(request: Request):
    # ... create post ...
    inertia.flash(request, "Post created!", type="success")
    return RedirectResponse(url="/posts", status_code=303)

Access in React:

export default function Index({ flash }) {
  return (
    <div>
      {flash && <Alert type={flash.type}>{flash.message}</Alert>}
    </div>
  );
}

Database Module

Type-safe database queries with Pydantic validation:

from sqlalchemy import MetaData, Table, Column, Integer, String, select
from pydantic import BaseModel
from vegabase.db import Database, query

# Define schema
metadata = MetaData()
users = Table('users', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String),
    Column('email', String),
)

# Define model
class User(BaseModel):
    id: int
    name: str
    email: str

# Query with full type safety
db = Database("sqlite:///app.db")

with db.connection() as conn:
    user = conn.one(query(User, select(users).where(users.c.id == 42)))
    print(user.name)  # IDE autocomplete works!
    
    all_users = conn.all(query(User, select(users)))  # Returns List[User]

Query Methods

Method Returns On Empty
one() Single T Raises NotFoundError
maybe_one() T | None Returns None
many() List[T] Raises NotFoundError
all() List[T] Returns []

Async Support

from vegabase.db import AsyncDatabase

db = AsyncDatabase("sqlite+aiosqlite:///app.db")

async with db.connection() as conn:
    users = await conn.all(query(User, select(users)))

Schema Management

No migration files โ€” just compare and apply:

vegabase db plan   # Preview changes
vegabase db apply  # Apply changes

Project Structure

my-app/
โ”œโ”€โ”€ backend/
โ”‚   โ”œโ”€โ”€ main.py           # FastAPI application
โ”‚   โ””โ”€โ”€ db/
โ”‚       โ””โ”€โ”€ schema.py     # Database tables
โ”œโ”€โ”€ frontend/
โ”‚   โ”œโ”€โ”€ pages/            # React pages (auto-discovered)
โ”‚   โ”œโ”€โ”€ components/       # Reusable components
โ”‚   โ””โ”€โ”€ styles.css        # Tailwind entry point
โ”œโ”€โ”€ static/dist/          # Generated assets (gitignored)
โ”œโ”€โ”€ .vegabase/            # Generated entry files (gitignored)
โ”œโ”€โ”€ package.json          # JS dependencies
โ””โ”€โ”€ pyproject.toml        # Python dependencies

Production

# Build optimized bundles
vegabase build

# Start the SSR server (background)
vegabase ssr &

# Start the FastAPI server
APP_ENV=production python -m backend.main

Examples

See the examples/ directory:

  • basic-app โ€” Minimal single-page example
  • posts โ€” CRUD app with flash messages and database
  • ticketing โ€” Full app with authentication, multi-page routing

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vegabase-0.1.0.tar.gz (25.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vegabase-0.1.0-py3-none-any.whl (34.6 kB view details)

Uploaded Python 3

File details

Details for the file vegabase-0.1.0.tar.gz.

File metadata

  • Download URL: vegabase-0.1.0.tar.gz
  • Upload date:
  • Size: 25.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.29

File hashes

Hashes for vegabase-0.1.0.tar.gz
Algorithm Hash digest
SHA256 099e0205c653f002cbec86b1c8b3c871b8563ac0b46527338290088d34f89902
MD5 2313935a20e718c06067e943b8d06371
BLAKE2b-256 e84dcf981919ee282864b1beb7bf91221adcca863c2938fc382ea5f296375c7d

See more details on using hashes here.

File details

Details for the file vegabase-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vegabase-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.29

File hashes

Hashes for vegabase-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e8b7608564b93bfc8ebd502d082609456007faed09f70f35a2c774c481ff7587
MD5 7b6d9416685efb8454b733fb9e9817fd
BLAKE2b-256 3e0159c0a4c0361e25c99cfdaa4789df8620346e63e844b2bbec7007ce3cbb62

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page