This file provides context for AI assistants working on this project.
Component Framework is a Python library for building server-side components with LiveView-style interactivity. It provides a framework-agnostic core with adapters for FastAPI, Django, and Litestar.
Status: Beta (0.4.0-beta) Language: Python 3.11+ License: MIT
- Framework Independence - Core logic separated from web framework
- Component Lifecycle - mount → hydrate → handle_event → render → dehydrate
- State Management - Server-owned state with JSON serialization
- Event Routing - Convention-based handlers (
on_<event>) - Pluggable Rendering - Support for multiple template engines
component_framework/
├── core/ # Framework-agnostic
│ ├── component.py # Base Component + async_dispatch
│ ├── form.py # Form validation (Pydantic)
│ ├── streaming.py # StreamingComponent + SSE support
│ ├── websocket.py # WebSocket manager
│ ├── registry.py # Component registration
│ ├── renderer.py # Renderer interface
│ ├── state.py # State storage
│ ├── permissions.py # Permission classes (Beta)
│ └── composition.py # Slot + composite components (Beta)
│
├── adapters/ # Framework-specific
│ ├── fastapi.py # FastAPI HTTP + SSE
│ ├── fastapi_websocket.py
│ ├── litestar.py # Litestar HTTP + SSE
│ ├── litestar_websocket.py
│ ├── django_*.py
│ ├── django_permissions.py # FBV decorators (Beta)
│ ├── django_ratelimit.py # RateLimitMixin (Beta)
│ └── jinjax_renderer.py
│
├── testing.py # ComponentTestCase + fixtures (Beta)
└── templatetags/ # Django templates
- Formatter: ruff format
- Linter: ruff check
- Type checker: ty (Astral's Rust-based type checker)
- Line length: 100 characters
- Type hints: Required for public APIs
- Docstrings: Required for classes and public methods
- Pre-commit: ruff + ty (see
.pre-commit-config.yaml)
- Use pytest for tests
- Components are pure Python - test without HTTP
- Mock renderers for unit tests
- Integration tests in examples/
When adding new features:
- Core first - Add to core/ if framework-agnostic
- Adapters second - Add framework-specific implementations
- Examples third - Demonstrate in examples/
- Document - Update docs/ and docstrings
- Test - Add tests in tests/
Components should:
- Extend
Componentbase class - Use
@registry.register("name")decorator - Implement lifecycle methods (mount, on_events)
- Manage state via
self.statedict - Not contain domain logic (use models/services)
- Raise
ComponentErrorfor component-specific errors - Raise
EventNotFoundErrorfor missing handlers - Log exceptions with
logging.exception() - Return user-friendly error messages
src/component_framework/core/component.py- Base Component class (200 lines)src/component_framework/core/form.py- Form validation (200 lines)src/component_framework/core/websocket.py- WebSocket support (250 lines)
src/component_framework/adapters/django_views.py- Views (FBV + CBV, 500 lines)src/component_framework/adapters/django_model.py- Model binding (200 lines)src/component_framework/templatetags/components.py- Template tags
examples/fastapi_example.py- FastAPI demoexamples/django_example/- Complete Django app with 4 components
docs/server_component_spec.md- Original specificationdocs/DJANGO_IMPLEMENTATION.md- Django guidedocs/CBV_GUIDE.md- Class-based views guidedocs/make.py- pdoc build script (callsjust docs-build)docs/update_gh_pages.py- CI helper: versions.json + root index for GitHub Pages- API reference: https://fsecada01.github.io/component-framework/
- Create
adapters/your_framework.py - Implement renderer class extending
Renderer - Create endpoint handler
- Add optional WebSocket support
- Document in docs/
- Add example in examples/
- Add method to
Componentbase class - Update lifecycle documentation
- Add tests
- Update examples
- Document in docstrings
- Write failing test first
- Fix bug
- Ensure test passes
- Check no regressions (run full test suite)
- Update documentation if needed
- State must be JSON-serializable
- No automatic CSRF for WebSockets (manual handling required)
- Component IDs generated client-side (could conflict)
- CacheMixin requires Django cache backend configuration
- Query optimization is manual (select_related, prefetch_related)
All Beta roadmap items are implemented and test-covered:
- Permission classes (
AllowAny,IsAuthenticated,IsStaff,IsSuperuser,DjangoModelPermission) - FBV permission decorators returning JSON 401/403 (no redirects)
- Rate limiting (
RateLimitMixin) - Component caching (
CacheMixin) - Optimistic UI (
OptimisticMixin+get_optimistic_patch()) - Component composition (
SlotComponent,CompositeComponent) - Testing utilities (
ComponentTestCase,dispatch_event,assert_state) - Versioned API docs via pdoc + GitHub Pages
- Litestar adapter (
[litestar]extra) — HTTP, WebSocket, SSE - Async event handlers (
async_dispatch()/async_handle_event()) - SSE streaming (
StreamingComponentwith async generator handlers) - State size guard (configurable warning at 64 KB, hard limit at 512 KB)
- JS double-serialisation fix in
component-client.js
- Stable, frozen public API
- Performance benchmarks and optimisation
- Devtools / inspector
- Component marketplace
- Full user guide and tutorials
- pydantic >= 2.0 (validation)
- No web framework required
- fastapi >= 0.109
- uvicorn (server)
- jinjax >= 0.41 (rendering)
- litestar >= 2.0
- jinja2 >= 3.1
- django >= 4.2
- channels >= 4.0 (WebSocket)
- django-cotton >= 0.9 (optional)
- pytest >= 7.4
- pytest-asyncio >= 0.21
- httpx >= 0.26
- ruff >= 0.1
- ty >= 0.0.18 (type checker)
- pdoc >= 14.0 (API docs)
- pre-commit >= 3.5
- prek (pre-commit hooks)
- just (task runner, cross-platform)
- Test components in isolation
- Mock renderers
- Test lifecycle methods
- Test event routing
- Test state serialization
- Test with real frameworks
- Test HTTP endpoints
- Test WebSocket connections
- Test database interactions
- FastAPI example should work
- Django example should work
- All components should render
- Component dispatch: < 1ms (in-memory)
- State serialization: < 1ms (JSON)
- Full HTTP cycle: ~10-20ms (local)
- WebSocket latency: < 10ms (local)
Optimize:
- Query optimization (select_related, prefetch_related)
- State size (keep minimal)
- Template rendering (cache where possible)
- WebSocket broadcasting (use Redis channels)
- CSRF protection required for mutations
- Input validation (Pydantic schemas)
- State validation (don't trust client)
- Permission checks (use Django permissions/FastAPI dependencies)
- Rate limiting (for production)
- XSS prevention (escape output)
- Check component registered:
registry.list() - Check renderer configured:
Component.renderer - Check template exists
- Check for exceptions in logs
- Check handler exists:
hasattr(component, 'on_event') - Check payload matches signature
- Check state is being passed correctly
- Check HTMX configuration
- Check connection established
- Check subscription active
- Check message format
- Check channel layer (Django)
@registry.register("hello")
class Hello(Component):
template_name = "hello.html"
def mount(self):
self.state["message"] = "Hello World"class MySchema(BaseModel):
name: str
email: EmailStr
@registry.register("my_form")
class MyForm(FormComponent):
schema = MySchema
def on_submit(self):
# self.validated_data is type-safe
save_data(self.validated_data)@registry.register("editor")
class Editor(DjangoModelComponent):
model = MyModel
state_fields = ["field1", "field2"]
def on_save(self):
self.update_instance_from_state()
self.save_instance()This is a beta project. Core APIs are stable; minor changes before 1.0.
When contributing:
- Open issue first for major changes
- Follow code style (ruff)
- Add tests
- Update docs
- Keep PRs small and focused
- Check docs/ directory
- Look at examples/
- Read tests/
- Open a GitHub issue
Primary:
- Framework-agnostic core
- Easy to use
- Easy to extend
- Good DX
Non-Goals:
- Replacing React/Vue
- Full ORM
- Specific template engine
- Client-side routing
MIT - See LICENSE file