Skip to main content

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

Project description

Vegabase

Full-stack React + Python with zero configuration.

Build modern React applications powered by FastAPI, Bun, TanStack Router, 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 bun

# Terminal 2: Backend
vegabase dev py

Visit http://localhost:8000 🎉

CLI Commands

Command Description
vegabase init Create a new project
vegabase dev bun Start Bun dev server (SSR + hot reload)
vegabase dev py Start Python dev server
vegabase build Build optimized production bundles
vegabase start bun Start SSR server for production
vegabase start py Start Python 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 ReactRenderer

react = ReactRenderer(app)

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

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

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

# Static: Pure HTML, no JavaScript bundle
await react.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="...")
react = ReactRenderer(app)

@app.post("/posts/create")
async def create_post(request: Request):
    # ... create post ...
    react.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

Configuration

Vegabase uses Dynaconf for layered configuration with environment support.

Settings Files

Create any of these in your project root (loaded in order, later overrides earlier):

settings.yaml          # Base settings
settings.toml          # Alternative format
.secrets.yaml          # Sensitive values (gitignored)
settings.local.yaml    # Local overrides (gitignored)

Environment Layering

# settings.yaml
default:
  DATABASE_URL: "sqlite:///app.db"

development:
  DEBUG: true

production:
  DATABASE_URL: "postgresql://..."

Switch environments with VEGABASE_APP_ENV:

VEGABASE_APP_ENV=production python -m backend.main

Accessing Settings

from vegabase import settings

print(settings.DATABASE_URL)
print(settings.get("OPTIONAL_KEY", default="fallback"))

All settings can be overridden via environment variables with VEGABASE_ prefix:

VEGABASE_DATABASE_URL="postgresql://..." python -m backend.main

Logging

Vegabase includes structured logging out of the box:

  • Request timing: Every request logs method, path, status, and duration
  • Consistent format: ISO timestamps across Python and Bun servers
  • Customizable: Override via LOGGING in your settings file

Example output:

2026-01-04T21:09:01+0000 INFO vegabase.access GET /posts 200 45ms
2026-01-04T21:09:01+0000 INFO vegabase.access POST /posts/create 303 123ms

Customize logging in settings.yaml:

default:
  LOGGING:
    dynaconf_merge: true  # Extend defaults instead of replacing
    root:
      level: DEBUG

Production

# Build optimized bundles
vegabase build

# Start the SSR server (background)
vegabase start bun &

# Start the FastAPI server
vegabase start py

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.2.1.tar.gz (34.6 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.2.1-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for vegabase-0.2.1.tar.gz
Algorithm Hash digest
SHA256 904b56ff0f315c706413be9edf9fcea701bfa3dfa18618ca59359e2396154bab
MD5 62267d2b32b5dd4135ede57f17e0f0a8
BLAKE2b-256 ab2bf9dd4344f010d7a75d19654fbdaca70b002b6b6a69c03bb13ee7881f8616

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for vegabase-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c679f30398078ece7059b5fb18d2dc5607c9386ac0d4259894d4393912246b8
MD5 63500621f3c29fa0cfb216aeeedfdd01
BLAKE2b-256 e78bcb99998851288197cab77257d83058ba34b51daaa520689da5006fb66fc3

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