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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
099e0205c653f002cbec86b1c8b3c871b8563ac0b46527338290088d34f89902
|
|
| MD5 |
2313935a20e718c06067e943b8d06371
|
|
| BLAKE2b-256 |
e84dcf981919ee282864b1beb7bf91221adcca863c2938fc382ea5f296375c7d
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8b7608564b93bfc8ebd502d082609456007faed09f70f35a2c774c481ff7587
|
|
| MD5 |
7b6d9416685efb8454b733fb9e9817fd
|
|
| BLAKE2b-256 |
3e0159c0a4c0361e25c99cfdaa4789df8620346e63e844b2bbec7007ce3cbb62
|