Modern Bootstrap 5 components for FastHTML - Build beautiful UIs in pure Python
Project description
FastStrap
Modern Bootstrap 5 components for FastHTML - Build beautiful web UIs in pure Python with zero JavaScript knowledge.
Why FastStrap?
FastHTML is amazing for building web apps in pure Python, but it lacks pre-built UI components. FastStrap fills that gap by providing:
✅ 51 Bootstrap components - Buttons, Cards, Modals, Forms, Navigation, and more
✅ Zero JavaScript knowledge required - Components just work
✅ No build steps - Pure Python, no npm/webpack/vite
✅ Full HTMX integration - Dynamic updates without page reloads
✅ Zero-JS animations - Beautiful effects with pure CSS (Fx module)
✅ Dark mode built-in - Automatic theme switching
✅ Type-safe - Full type hints for better IDE support
✅ Pythonic API - Intuitive kwargs style
✅ Enhanced customization - Slot classes, CSS variables, themes, and more
✅ 95% documented - Comprehensive docs with examples
Quick Start
Installation
pip install faststrap
Hello World
from fasthtml.common import FastHTML, serve
from faststrap import add_bootstrap, Card, Button, create_theme
app = FastHTML()
# Use built-in theme or create custom
theme = create_theme(primary="#7BA05B", secondary="#48C774")
add_bootstrap(app, theme=theme, theme="dark")
@app.route("/")
def home():
return Card(
"Welcome to FastStrap! Build beautiful UIs in pure Python.",
header="Hello World 👋",
footer=Button("Get Started", variant="primary")
)
serve()
That's it! You now have a modern, responsive web app with zero JavaScript.
Working with Static Files
Faststrap V0.5.1+ includes a helper to easily mount your own static files (images, CSS, etc.):
from faststrap import mount_assets
# Mount your "assets" directory at "/assets" URL
mount_assets(app, "assets")
# Use in your app
Img(src="/assets/logo.png")
Div(style="background-image: url('/assets/hero.jpg')")
See Static Files Guide for more details.
Enhanced Features
1. Enhanced Attribute Handling
Faststrap now supports advanced attribute handling:
from faststrap import Button
# Style dict and CSS variables
Button(
"Styled Button",
style={"background-color": "#7BA05B", "border": "none"},
css_vars={"--bs-btn-padding-y": "0.75rem", "--bs-btn-border-radius": "12px"},
data={"id": "123", "type": "demo"},
aria={"label": "Styled button"},
)
# Filter None/False values automatically
Button("Test", disabled=None, hidden=False) # None/False values are dropped
2. CloseButton Helper
Reusable close button for alerts, modals, and drawers:
from faststrap import CloseButton, Alert
# Use in alerts
Alert(
"This alert uses CloseButton helper",
variant="info",
dismissible=True,
)
# Use in modals/drawers (automatically used)
3. Expanded Button Component
More control over button appearance and behavior:
from faststrap import Button
# Render as link
Button("As Link", as_="a", href="/page", variant="secondary")
# Loading states with custom text
Button("Loading", loading=True, loading_text="Please wait...", spinner=True)
# Full width, pill, active states
Button("Full Width", full_width=True, variant="info")
Button("Pill", pill=True, variant="warning")
Button("Active", active=True, variant="success")
# Icon and spinner control
Button("Icon + Spinner", icon="check-circle", spinner=True, icon_pos="start")
4. Slot Class Overrides
Fine-grained control over component parts:
from faststrap import Card, Modal, Drawer, Dropdown
# Card with custom slot classes
Card(
"Content",
header="Custom Header",
footer="Custom Footer",
header_cls="bg-primary text-white p-3",
body_cls="p-4",
footer_cls="text-muted",
)
# Modal with custom classes
Modal(
"Modal content",
title="Custom Modal",
dialog_cls="shadow-lg",
content_cls="border-0",
header_cls="bg-primary text-white",
body_cls="p-4",
)
# Drawer with custom classes
Drawer(
"Drawer content",
title="Custom Drawer",
header_cls="bg-success text-white",
body_cls="p-4",
)
# Dropdown with custom classes
Dropdown(
"Option 1", "Option 2",
label="Custom Dropdown",
toggle_cls="custom-toggle",
menu_cls="custom-menu",
item_cls="custom-item",
)
5. Theme System
Create and apply custom themes:
from faststrap import create_theme, add_bootstrap
# Create custom theme
my_theme = create_theme(
primary="#7BA05B",
secondary="#48C774",
info="#36A3EB",
warning="#FFC107",
danger="#DC3545",
success="#28A745",
light="#F8F9FA",
dark="#343A40",
)
# Use built-in themes
add_bootstrap(app, theme="green-nature") # or "blue-ocean", "dark-mode", etc.
# Or use custom theme
add_bootstrap(app, theme=my_theme)
Available built-in themes:
green-natureblue-oceanpurple-magicred-alertorange-sunsetteal-oasisindigo-nightpink-lovecyan-skygray-mistdark-modelight-mode
6. Registry Metadata
Components now include metadata about JavaScript requirements:
from faststrap.core.registry import list_components, get_component
# List all components
components = list_components()
# Check if component requires JS
modal = get_component("Modal")
# Modal is registered with requires_js=True
Available Components (51 Total)
All components are production-ready with comprehensive documentation, HTMX integration, and accessibility features.
Forms (13 Components)
- Button - Buttons with variants, sizes, loading states, icons
- CloseButton - Reusable close button for dismissible components
- ButtonGroup - Grouped buttons and toolbars
- ButtonToolbar - Multiple button groups
- Input - Text inputs with validation and types
- Select - Dropdown selections with multiple options
- Checkbox - Checkboxes with inline/stacked layouts
- Radio - Radio buttons with groups
- Switch - Toggle switches
- Range - Range sliders
- FileInput - File upload inputs
- InputGroup - Input addons (text, buttons, icons)
- FloatingLabel - Animated floating labels
Display (10 Components)
- Card - Content containers with headers/footers/images
- Badge - Status indicators and labels
- Table - Data tables with striped, hover, bordered styles
- Figure - Images with captions
- Icon - Bootstrap Icons helper (2,000+ icons)
- EmptyState - Empty state placeholders
- StatCard - Statistics display cards
- Image - Responsive images with fluid, thumbnail, rounded, alignment
- Carousel - Auto-play image sliders with controls, indicators, fade
- Placeholder - Skeleton loading with glow/wave animations
Feedback (10 Components)
- Alert - Dismissible alerts with variants
- Modal - Dialog boxes and confirmations
- ConfirmDialog - Pre-configured confirmation modals
- Toast - Auto-dismiss notifications
- SimpleToast - Quick toast helper
- ToastContainer - Toast positioning container
- Spinner - Loading indicators (border/grow)
- Progress - Progress bars with stripes/animation
- ProgressBar - Individual progress bar component
- Tooltip - Hover tooltips
- Popover - Click popovers
- Collapse - Show/hide content areas
Navigation (14 Components)
- Navbar - Responsive navigation bars
- NavbarModern - Glassmorphism navbar
- Tabs - Navigation tabs and pills
- TabPane - Tab content panes
- Dropdown - Contextual dropdown menus
- DropdownItem - Dropdown menu items
- DropdownDivider - Dropdown separators
- Breadcrumb - Navigation breadcrumbs
- Pagination - Page navigation
- Accordion - Collapsible panels
- AccordionItem - Individual accordion panels
- ListGroup - Versatile content lists
- ListGroupItem - List items with badges/variants
- Drawer - Offcanvas side panels
- Scrollspy - Auto-updating navigation based on scroll
- SidebarNavbar - Premium vertical sidebar for dashboards
- GlassNavbar - Premium glassmorphism navbar
Layout (4 Components)
- Container - Responsive containers (fixed/fluid)
- Row - Grid rows with gutters
- Col - Grid columns with breakpoints
- Hero - Hero sections with backgrounds/overlays
Layouts (2 Composed Layouts)
- DashboardLayout - Admin panel with sidebar
- LandingLayout - Marketing page layout
Effects (1 Module)
- Fx - Zero-JS animations and visual effects
- Entrance animations (fade, slide, zoom, bounce)
- Hover interactions (lift, scale, glow, tilt)
- Loading states (spin, pulse, shimmer)
- Visual effects (glass, shadows, gradients)
- Speed and delay modifiers
Patterns (5 Composed Components)
- Feature - Feature highlight component
- FeatureGrid - Grid of features
- PricingTier - Pricing card component
- PricingGroup - Group of pricing tiers
Documentation Coverage
- 95% documented (43/45 components)
- All docs include:
- Bootstrap CSS class guides
- HTMX integration examples
set_component_defaultsusage- Responsive design patterns
- Accessibility best practices
- Common recipes and patterns
View docs: https://faststrap-org.github.io/Faststrap/
Examples
Comprehensive examples organized by learning path:
01_getting_started/
hello_world.py- Your first Faststrap appfirst_card.py- Working with componentssimple_form.py- Building formsadding_htmx.py- HTMX interactivity
03_real_world_apps/
blog/- Complete blog with posts, comments, admincalculator/- HTMX-powered calculatorgame/- Tic-tac-toe with win detectionecommerce/- E-commerce store (existing)
04_advanced/
effects_showcase.py- All Faststrap effects democustom_themes.py- Theme customizationcomponent_defaults.py- Global configuration
See: examples/README.md for complete guide
| Dropdown | Contextual menus with split buttons | ✅ | | Input | Text form controls with validation | ✅ | | Select | Dropdown selections (single/multiple) | ✅ | | Breadcrumb | Navigation trail with icons | ✅ | | Pagination | Page navigation with customization | ✅ | | Spinner | Loading indicators (border/grow) | ✅ | | Progress | Progress bars with animations | ✅ |
✅ Phase 4A (v0.4.0) - 10 Components
| Component | Description | Status |
|---|---|---|
| Table | Responsive data tables | ✅ |
| Accordion | Collapsible panels | ✅ |
| Checkbox | Checkbox form controls | ✅ |
| Radio | Radio button controls | ✅ |
| Switch | Toggle switch variant | ✅ |
| Range | Slider input control | ✅ |
| ListGroup | Versatile lists | ✅ |
| Collapse | Show/hide content | ✅ |
| InputGroup | Prepend/append addons | ✅ |
| FloatingLabel | Animated label inputs | ✅ |
✅ Phase 4B (v0.4.5) - 8 Components
| Component | Description | Status |
|---|---|---|
| FileInput | File uploads with preview | ✅ |
| Tooltip | Contextual hints | ✅ |
| Popover | Rich overlays | ✅ |
| Figure | Image + caption | ✅ |
| ConfirmDialog | Modal confirmation preset | ✅ |
| EmptyState | Placeholder component | ✅ |
| StatCard | Metric display card | ✅ |
| Hero | Landing page hero section | ✅ |
🗓️ Phase 5+ (v0.5.0 - v1.0.0)
- Sidebar, Footer, DashboardLayout
- DataTable with sorting/filtering/pagination
- FormWizard, Stepper
- Timeline, ProfileDropdown, SearchBar
- Carousel, MegaMenu, NotificationCenter
- And 40+ more components...
Target: 100+ components by v1.0.0 (Aug 2026)
See ROADMAP.md for complete timeline.
Core Concepts
1. Adding Bootstrap to Your App
from fasthtml.common import FastHTML
from faststrap import add_bootstrap, create_theme
app = FastHTML()
# Basic setup (includes default FastStrap favicon)
add_bootstrap(app)
# With dark theme
add_bootstrap(app, theme="dark")
# Custom theme
theme = create_theme(primary="#7BA05B", secondary="#48C774")
add_bootstrap(app, theme=theme)
# Using CDN
add_bootstrap(app, use_cdn=True)
2. Using Components
All components follow Bootstrap's conventions with Pythonic names:
from faststrap import Button, Badge, Alert, Input, Select, Tabs
# Button with HTMX
Button("Save", variant="primary", hx_post="/save", hx_target="#result")
# Form inputs
Input("email", input_type="email", label="Email Address", required=True)
Select("country", ("us", "USA"), ("uk", "UK"), label="Country")
# Navigation tabs
Tabs(
("home", "Home", True),
("profile", "Profile"),
("settings", "Settings")
)
3. HTMX Integration
All components support HTMX attributes:
# Dynamic button
Button("Load More", hx_get="/api/items", hx_swap="beforeend")
# Live search input
Input("search", placeholder="Search...", hx_get="/search", hx_trigger="keyup changed delay:500ms")
# Dynamic dropdown
Select("category", ("a", "A"), ("b", "B"), hx_get="/filter", hx_trigger="change")
4. Responsive Grid System
from faststrap import Container, Row, Col
Container(
Row(
Col("Left column", cols=12, md=6, lg=4),
Col("Middle column", cols=12, md=6, lg=4),
Col("Right column", cols=12, md=12, lg=4)
)
)
Examples
Form with Validation
from faststrap import Input, Select, Button, Card
Card(
Input(
"email",
input_type="email",
label="Email Address",
placeholder="you@example.com",
required=True,
help_text="We'll never share your email"
),
Input(
"password",
input_type="password",
label="Password",
required=True,
size="lg"
),
Select(
"country",
("us", "United States"),
("uk", "United Kingdom"),
("ca", "Canada"),
label="Country",
required=True
),
Button("Sign Up", variant="primary", type="submit", cls="w-100"),
header="Create Account"
)
Navigation with Tabs
from faststrap import Tabs, TabPane, Card
Card(
Tabs(
("profile", "Profile", True),
("settings", "Settings"),
("billing", "Billing")
),
Div(
TabPane("Profile content here", tab_id="profile", active=True),
TabPane("Settings content here", tab_id="settings"),
TabPane("Billing content here", tab_id="billing"),
cls="tab-content p-3"
)
)
Loading States
from faststrap import Spinner, Progress, Button
# Spinner in button
Button(
Spinner(size="sm", label="Loading..."),
" Processing...",
variant="primary",
disabled=True
)
# Progress bar
Progress(75, variant="success", striped=True, animated=True, label="75%")
# Stacked progress
Div(
ProgressBar(30, variant="success"),
ProgressBar(20, variant="warning"),
ProgressBar(10, variant="danger"),
cls="progress"
)
Pagination
from faststrap import Pagination, Breadcrumb
# Breadcrumb
Breadcrumb(
(Icon("house"), "/"),
("Products", "/products"),
("Laptops", None)
)
# Page navigation
Pagination(
current_page=5,
total_pages=20,
size="lg",
align="center",
show_first_last=True
)
Project Structure
faststrap/
├── src/faststrap/
│ ├── __init__.py # Public API
│ ├── core/
│ │ ├── assets.py # Bootstrap injection + favicon
│ │ ├── base.py # Component base classes
│ │ ├── registry.py # Component registry
│ │ └── theme.py # Theme system
│ ├── components/
│ │ ├── forms/ # Button, Input, Select
│ │ ├── display/ # Card, Badge
│ │ ├── feedback/ # Alert, Toast, Modal, Spinner, Progress
│ │ ├── navigation/ # Navbar, Drawer, Tabs, Dropdown, Breadcrumb, Pagination
│ │ └── layout/ # Container, Row, Col
│ ├── static/ # Bootstrap assets + favicon
│ │ ├── css/
│ │ │ ├── bootstrap.min.css
│ │ │ └── bootstrap-icons.min.css
│ │ ├── js/
│ │ │ └── bootstrap.bundle.min.js
│ │ └── favicon.svg # Default FastStrap favicon
│ ├── templates/ # Component templates
│ └── utils/
│ ├── icons.py # Bootstrap Icons
│ ├── static_management.py # Assets extended helper functions
│ └── attrs.py # Centralized attribute conversion
├── tests/ # 219 tests (80% coverage)
├── examples/ # Demo applications
│ └── demo_all.py # Comprehensive demo
└── docs/ # Documentation
Development
Prerequisites
- Python 3.10+
- FastHTML 0.6+
- Git
Setup
# Clone repository
git clone https://github.com/Faststrap-org/Faststrap.git
cd Faststrap
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=faststrap
# Type checking
mypy src/faststrap
# Format code
black src/faststrap tests
ruff check src/faststrap tests
Troubleshooting
Static Files Not Loading (404 Errors)
Fixed in v0.4.6+! If you're seeing 404 errors for Bootstrap CSS/JS files, update to the latest version:
pip install --upgrade faststrap
Theme Not Applied with fast_app()
When using fast_app(), add data_bs_theme to your root element:
app, rt = fast_app()
add_bootstrap(app, mode="light")
@rt("/")
def get():
return Div(
YourContent(),
data_bs_theme="light", # ← Add this for proper theming
)
Styles Not Loading with Custom Html()
When manually creating Html() + Head(), include *app.hdrs:
@app.route("/")
def get():
return Html(
Head(
Title("My App"),
*app.hdrs, # ← Required for Faststrap styles
),
Body(YourContent())
)
For more help, see TROUBLESHOOTING.md
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Quick Contribution Guide
- Pick a component from ROADMAP.md Phase 4
- Follow patterns in BUILDING_COMPONENTS.md
- Write tests - Aim for 100% coverage (8-15 tests per component)
- Submit PR - We review within 48 hours
Documentation
- 📖 Component Spec: COMPONENT_SPEC.md
- 🏗️ Building Guide: BUILDING_COMPONENTS.md
- 🗺️ Roadmap: ROADMAP.md
- 🤝 Contributing: CONTRIBUTING.md
- 📝 Changelog: CHANGELOG.md
Troubleshooting
Static Files Not Loading (404 Errors)
Problem: Background images or custom assets return 404 Not Found.
Solution: Use mount_assets() to properly mount your static directory:
from faststrap import mount_assets
mount_assets(app, "assets") # Mounts assets/ at /assets/
Then reference files with the correct path:
Div(style="background-image: url('/assets/hero-bg.jpg')") # ✅ Correct
Div(style="background-image: url('/hero-bg.jpg')") # ❌ Wrong
See Static Files for full guide.
Roadmap
v0.3.1 (Current - December 2025)
- ✅ 20 components (12 + 8 new)
- ✅ 219 tests, 80% coverage
- ✅ Centralized
convert_attrs()utility - ✅ Default FastStrap favicon
- ✅ Full HTMX integration
- ✅ Enhanced customization (slot classes, CSS vars, themes)
- ✅ Component defaults system with
resolve_defaults()
v0.4.0 (Phase 4A - Complete)
- ✅ Table, Accordion, Checkbox, Radio, Switch
- ✅ Range, ListGroup, Collapse, InputGroup, FloatingLabel
- ✅ 30 components total
v0.4.5 (Phase 4B - Complete)
- ✅ FileInput, Tooltip, Popover, Figure
- ✅ ConfirmDialog, EmptyState, StatCard, Hero
- ✅ 38 components total
v0.5.0 (Phase 5 - Mar 2026)
- Sidebar, Footer, DashboardLayout
- Timeline, Carousel, MegaMenu
- 50 components total
v1.0.0 (Target Aug 2026)
- 100+ components
- Component playground
- Full documentation website
- Video tutorials
- Production ready
See ROADMAP.md for complete timeline.
Stats
- 38 components across 5 categories
- 219+ passing tests
- Zero custom JavaScript required
- Full HTMX integration
- Enhanced customization with slot classes, CSS variables, and themes
Support
- 📖 Documentation: GitHub README
- 🐛 Bug Reports: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 🎮 Discord: FastHTML Community
License
MIT License - see LICENSE file for details.
Acknowledgments
- FastHTML - The amazing pure-Python web framework
- Bootstrap - Battle-tested UI components
- HTMX - Dynamic interactions without complexity
- Contributors - Thank you! 🙏
Built with ❤️ for the FastHTML community
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 faststrap-0.5.2.tar.gz.
File metadata
- Download URL: faststrap-0.5.2.tar.gz
- Upload date:
- Size: 583.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea88ebb23b0658f86ccebb40f8611c7349c5add81bbb98ca58059d7acb907084
|
|
| MD5 |
334025523efdf2c4204caaacc71012db
|
|
| BLAKE2b-256 |
9c6883f432ad888386b92a5803685b4a5556b0e7d58fb8f2b616fc716ff9ca25
|
Provenance
The following attestation bundles were made for faststrap-0.5.2.tar.gz:
Publisher:
publish.yml on Faststrap-org/Faststrap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
faststrap-0.5.2.tar.gz -
Subject digest:
ea88ebb23b0658f86ccebb40f8611c7349c5add81bbb98ca58059d7acb907084 - Sigstore transparency entry: 833742815
- Sigstore integration time:
-
Permalink:
Faststrap-org/Faststrap@8b756f86f02d674e42eb0cc3295ebcc1854fd653 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Faststrap-org
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8b756f86f02d674e42eb0cc3295ebcc1854fd653 -
Trigger Event:
release
-
Statement type:
File details
Details for the file faststrap-0.5.2-py3-none-any.whl.
File metadata
- Download URL: faststrap-0.5.2-py3-none-any.whl
- Upload date:
- Size: 484.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01d26fdf2f84a3da5f192951c08b04f94907a55035ddf8acb12c977634b2798c
|
|
| MD5 |
1b6ca788d1c992305e196d73082b6dfe
|
|
| BLAKE2b-256 |
03abab388349ae857182db3db4eaac5992d4337d6070b90b787de098807091ae
|
Provenance
The following attestation bundles were made for faststrap-0.5.2-py3-none-any.whl:
Publisher:
publish.yml on Faststrap-org/Faststrap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
faststrap-0.5.2-py3-none-any.whl -
Subject digest:
01d26fdf2f84a3da5f192951c08b04f94907a55035ddf8acb12c977634b2798c - Sigstore transparency entry: 833742816
- Sigstore integration time:
-
Permalink:
Faststrap-org/Faststrap@8b756f86f02d674e42eb0cc3295ebcc1854fd653 -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/Faststrap-org
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8b756f86f02d674e42eb0cc3295ebcc1854fd653 -
Trigger Event:
release
-
Statement type: