A Python web framework inspired by Next.js with file-based routing, SSR, and SSG and more
Project description
NextPy Framework
A Python web framework inspired by Next.js. Build modern web applications with file-based routing, server-side rendering (SSR), static site generation (SSG), and more.
Features
- File-based Routing - Pages in
pages/become routes automatically - Dynamic Routes -
[slug].pycreates dynamic URL segments - Server-Side Rendering -
get_server_side_propsfetches data per request - Static Site Generation -
get_static_propsbuilds pages at compile time - API Routes - Create API endpoints in
pages/api/ - HTMX Integration - SPA-like navigation without heavy JavaScript
- Jinja2 Templates - Powerful templating with layout inheritance
- Hot Reload - Instant updates on file changes during development
- Debug Panel - Built-in error overlay for development
- Components Library - Pre-built UI components (buttons, cards, forms)
- Tailwind CSS Integration - Utility-first CSS framework for rapid UI development
Installation
Via pip
pip install nextpy-framework
Development Install (Editable)
git clone https://github.com/nextpy/nextpy-framework.git
cd nextpy-framework
pip install -e .
This installs NextPy in editable mode, so changes to the source code take effect immediately.
Quick Start
1. Create a new project
nextpy create my-app
cd my-app
2. Install dependencies (Python & Node.js)
First, install Python dependencies:
pip install -e .
# or
pip install -r requirements.txt
Then, for Tailwind CSS, ensure you have Node.js and npm installed. Initialize npm and install Tailwind CSS:
npm init -y
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
3. Configure Tailwind CSS
Create tailwind.config.js in your project root:
// tailwind.config.js
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./templates/**/*.html', # Add this line for Jinja2 templates
],
theme: {
extend: {},
},
plugins: [],
};
Create postcss.config.js in your project root:
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Create styles.css in your project root (or a css folder) with Tailwind directives:
/* styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Ensure your main.py is configured to compile Tailwind CSS (this is automatically handled in new NextPy projects):
# main.py (excerpt)
import subprocess
# ...
try:
print("Compiling Tailwind CSS...")
subprocess.run(["npx", "tailwindcss", "-i", "./styles.css", "-o", "./public/tailwind.css"], check=True)
print("Tailwind CSS compiled successfully.")
except subprocess.CalledProcessError as e:
print(f"Error compiling Tailwind CSS: {e}")
except FileNotFoundError:
print("Error: npx or tailwindcss command not found. Make sure Node.js and Tailwind CSS are installed.")
# ...
Finally, link the compiled Tailwind CSS in your base HTML template (templates/_base.html):
<!-- templates/_base.html (excerpt) -->
<head>
<!-- ... other head elements ... -->
<link href="/public/tailwind.css" rel="stylesheet">
</head>
4. Run development server
nextpy dev
Visit http://localhost:5000 - your app starts with hot reload enabled!
5. Create a page
# pages/hello.py
def get_template():
return "hello.html"
async def get_server_side_props(context):
return {
"props": {
"message": "Hello, World!"
}
}
6. Create a template with Tailwind CSS
<!-- templates/hello.html -->
{% extends "_base.html" %}
{% block content %}
<h1 class="text-3xl font-bold underline">{{ message }}</h1>
{% endblock %}
Visit http://localhost:5000/hello - page updates instantly as you edit!
Project Structure
my-app/
├── pages/ # Your pages (file-based routing)
│ ├── index.py # Home page (/)
│ ├── about.py # About page (/about)
│ ├── blog/
│ │ ├── index.py # Blog listing (/blog)
│ │ └── [slug].py # Dynamic post (/blog/:slug)
│ └── api/
│ └── posts.py # API route (/api/posts)
├── templates/ # Jinja2 templates
│ ├── _base.html # Base layout
│ ├── components/ # Reusable components
│ │ ├── button.html
│ │ ├── card.html
│ │ └── form.html
│ └── index.html # Page templates
├── public/ # Static files (CSS, JS, images)
│ └── tailwind.css # Compiled Tailwind CSS
├── main.py # Entry point
├── requirements.txt # Python dependencies
├── package.json # Node.js dependencies
├── tailwind.config.js # Tailwind CSS configuration
├── postcss.config.js # PostCSS configuration
└── styles.css # Tailwind CSS directives
Package Architecture
NextPy is fully self-contained and tightly integrated:
Core Components
| Module | Purpose |
|---|---|
| nextpy/server/app.py | Creates FastAPI application with routing |
| nextpy/core/router.py | Scans pages/, templates/, APIs dynamically |
| nextpy/core/renderer.py | SSR with Jinja2 + data fetching |
| nextpy/core/builder.py | SSG with static HTML generation |
| nextpy/cli.py | CLI scaffolding & commands |
| nextpy/components/ | Button, card, form components |
| nextpy/middleware.py | Debug panel, error handling |
Setup Files
- pyproject.toml - Package metadata & dependencies
- setup.cfg - Build configuration
- MANIFEST.in - Include non-Python files
- LICENSE - MIT License
- README.md - Documentation
How It All Works Together
- CLI (
nextpy create myapp) scaffolds project structure - Router scans
pages/and maps files to routes - Renderer executes
get_server_side_propsand renders with Jinja2 - FastAPI serves pages and API routes
- Builder generates static files for SSG
- Watchdog detects file changes → automatic hot reload
- Debug Middleware shows errors in development
Installable Features
✅ Works with pip install -e . for local development
✅ All files tightly integrated (no external dependencies)
✅ Auto-discovery of pages, templates, APIs
✅ CLI includes scaffolding with example structure
✅ Hot reload watches pages/, templates/, nextpy/ directories
✅ Debug panel shows errors in browser
Data Fetching
Server-Side Rendering (SSR)
Fetch data on every request:
async def get_server_side_props(context):
# Runs on every request
data = await fetch_from_api()
return {"props": {"data": data}}
Static Site Generation (SSG)
Fetch data at build time:
async def get_static_props(context):
# Runs at build time
data = await fetch_from_api()
return {"props": {"data": data}}
async def get_static_paths():
# For dynamic routes - define which paths to pre-render
return {
"paths": [
{"params": {"slug": "post-1"}},
{"params": {"slug": "post-2"}},
]
}
API Routes
Create API endpoints in pages/api/:
# pages/api/users.py
async def get(request):
return {"users": [...]}
async def post(request):
data = await request.json()
return {"created": data}
async def put(request):
data = await request.json()
return {"updated": data}
async def delete(request):
return {"deleted": True}
Components
Use pre-built components via Jinja2 macros:
{% from "components/button.html" import button %}
{% from "components/card.html" import card %}
{% from "components/form.html" import input, textarea, select %}
{{ button("Click Me", "/action", "primary") }}
{{ card(title="My Card", content="Description", link="/details") }}
{{ input("name", "Full Name", "text", "John Doe", True) }}
Layouts & Nesting
Create nested layouts with template inheritance:
<!-- templates/_base.html (root) -->
<html>
<body>
<nav>...</nav>
<link href="/public/tailwind.css" rel="stylesheet"> # Added Tailwind CSS link
{% block content %}{% endblock %}
</body>
</html>
<!-- templates/_blog-layout.html (extends base) -->
{% extends "_base.html" %}
{% block content %}
<div class="blog-container">
{% block blog_content %}{% endblock %}
</div>
{% endblock %}
<!-- templates/blog/[slug].html (extends blog layout) -->
{% extends "_blog-layout.html" %}
{% block blog_content %}
<h1>{{ title }}</h1>
{% endblock %}
CLI Commands
nextpy dev # Start development server with hot reload & debug panel
nextpy build # Generate static files to out/
nextpy start # Start production server
nextpy routes # Display all registered routes
nextpy create # Create new project
Development Features
🔥 Hot Reload - File changes trigger instant server restart
🐛 Debug Panel - Error overlay with stack traces
📍 Route Listing - View all registered routes
🎯 Auto-discovery - Pages, templates, APIs loaded automatically
Tech Stack
- FastAPI - High-performance async web framework
- Uvicorn - Lightning-fast ASGI server
- Jinja2 - Powerful templating engine with inheritance
- Pydantic - Type-safe data validation
- Watchdog - File system monitoring for hot reload
- Click - Elegant CLI framework
- HTMX - Modern browser features without JavaScript complexity
- Tailwind CSS - Utility-first CSS framework
Production Deployment
# Build static files
nextpy build
# Start production server
nextpy start
For hosting:
- Heroku:
git push heroku main - Vercel: Static hosting (use
nextpy build) - Docker: Dockerfile ready
- VPS: Run
nextpy startwith process manager (systemd, supervisord)
Contributing
Contributions welcome! NextPy is MIT licensed.
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 nextpy_framework-1.1.1.tar.gz.
File metadata
- Download URL: nextpy_framework-1.1.1.tar.gz
- Upload date:
- Size: 51.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d133cc456846345a2f50cfff63ff9b83b2934c17750d28bb95296de8481ff64
|
|
| MD5 |
b250508fb3ff62a9e7b31f18c93a5659
|
|
| BLAKE2b-256 |
9a62f9ec22fb540348959e15d7accfb631821b2f514d6e9e0b778d29f84f471a
|
File details
Details for the file nextpy_framework-1.1.1-py3-none-any.whl.
File metadata
- Download URL: nextpy_framework-1.1.1-py3-none-any.whl
- Upload date:
- Size: 63.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1363bd7bf64929b454221ed3f4cb11343b45153108addd0302e709c2400701a
|
|
| MD5 |
21fd4a0e47c60c8d0665e1ea1d2483f3
|
|
| BLAKE2b-256 |
fca44877910c9b6e4ad6f01da5450b92bec32547d5fd81784ac7cadb67500d69
|