Skip to content

Changelog

Note

Tetra is still early in its development, and we can make no promises about API stability at this stage.

The intention is to stabilise the API prior to a v1.0 release, as well as implementing some additional functionality. After v1.0 we will move to using Semantic Versioning.

[0.9.3] – 2026-03-20

Fixed

  • fix smaller errors in forms and form validation, improve error messages

[0.9.2] – 2026-03-18

Added

  • Client-side Routing: Implement full client-side routing that informs the server of new routes. (Note: This feature is highly experimental and not meant for production).
  • Nested Routes: Improved Router to be nestable and delegate routes to sub-routers.
  • Router Registry: Introduced a global router registry with reverse and reverse_lazy support for components.
  • Allow BasicComponent to include simple JavaScript (without Alpine/state access).
  • Pass Tetra endpoint from server config to client instead of using hardcoded URLs.
  • Add "ws" hint when debugging navigation in the browser console.

Changed

  • Breaking change: Exclude context from saved component state per default to reduce state size and improve security.
  • Rename router_url to router_urls for consistency.
  • Remove compiled JavaScript assets from VCS to reduce repository noise.
  • Improve error messages when template HTML files are missing or when StateException is raised.

Fixed

  • Fix order of finding HTML templates, CSS, and JS files for components when base classes are involved.
  • Handle Django empty patterns returning / by converting to an empty string in the router.
  • Fix ReactiveComponent auto-generated key support.
  • Fix template resolution and JS discovery for directory-based components.
  • Fix return annotations and various typos/whitespace issues.
  • Ensure only the "default" library in Tetra is discovered to avoid conflicts.
  • Refactored tests and improved error handling in templates.

[0.9.1] – 2026-02-17

Fixed

  • WebSocket connections are now only established when a page actually renders a ReactiveComponent, not just when such classes exist in the codebase.
  • When ReactiveModels change, they now only update the instance channel, not the * collection* channel.

[0.9.0] – 2026-02-17

Added

  • Introduce group_registry for group validation and improve subscription handling
  • Introduce online status tracking
  • Offline Queue System: Automatic queueing and replay of component method calls when network is unavailable.
  • Stale Component State Handling: Components now gracefully handle cases where database objects their reference have been deleted/changed by another client.

Changed

  • JSON-based internal Calling Endpoint: Component method calls now use a unified JSON-based HTTP endpoint at /__tetra__/call/ instead of the previous component-specific URLs, providing a more consistent API structure.
  • Pickling/Unpickling now checks variables against a "safe list" of types.
  • rename Alpine store tetra_status to tetraStatus

Removed

  • Remove deprecated @public.subscribe decorator

[0.8.5] – 2026-02-01

Added

  • Improve subscription response handling
  • Raise ProtocolError for invalid Tetra protocol version

Changed

  • Rename component.data_updated to component.data_changed

[0.8.4] – 2026-02-01

Fixed

  • Fix error where another client could keep a stale component when two components are deleted locally.
  • Fix ReactiveComponent subscription by template tag attr

Changed

  • Rename component.data_updated to component.data_changed message type and Dispatcher/TetraConsumer method across backend and frontend

[0.8.3] – 2026-02-01

Added

  • Component Addition via WebSocket: Added ComponentDispatcher.component_created and client-side support for adding components dynamically via WebSockets.

Fixed

  • use actual user model for auto-subscribe channel name, instead of "user."
  • fix component key generation when key is not explicitly provided in template tag.
  • fix test compatibility with custom user models and playwright environments.
  • skip updates for focused fields to preserve user input during data updates

[0.8.2] - 2026-02-31

Added

  • Reactive Models: Introduced ReactiveModel to enable automatic WebSocket updates when Django models are saved or deleted.
  • Add support for a request sender id to filter server-side change events.

Fixed

  • Fixed signal connection reliability for ReactiveModel across various inheritance scenarios.
  • Ensured WebSocket scripts are only included when both reactive components/models are used and WebSocket support is detected.

[0.8.1] - 2026-01-31

Fixed

  • Fixed TypeError in _handleAutofocus when this.$root is undefined (e.g. if the component was removed from the DOM before the next tick).
  • Support enums (TextChoices, IntChoices!) and FileFields in pydantic validation.
  • Make client side redirects faster: don't render the component DOM before redirecting.

Added

  • allow component classes in routes

Changed

  • delegate rendering of components to BaseRenderer and ComponentRenderer classes
  • more robust schemata state validation using Pydantic's TypeAdapters for component attributes
  • Implementation of the Tetra Unified Protocol (Phase 1 & 2) for both HTTP method calls and WebSockets. This unifies communication into a consistent JSON envelope, moving metadata like Django messages from headers into the response body. Removed T-Response and T-Messages headers in favor of the unified protocol and inline script injection.
  • Removed all fallbacks and support for the legacy communication protocol.

[0.8.0] - 2026-01-26

Changed

  • Enhanced middleware efficiency by implementing a fast path for non-Tetra requests, including tests.
  • BasicComponents now don't use a Metaclass anymore, but __init_subclass__()

[0.7.3] - 2026-01-25

Fixed

  • Another fix (try?) for file upload vulnerabilities: don't include uploaded file names to form.data when invalid form is rendered. This one is tricky.

[0.7.2] - 2026-01-20

Fixed: improve file handling security and add tests for file upload vulnerabilities

[0.7.1] - 2026-01-14

Added

  • Incremental build support for libraries. Tetra now detects changes in component source files (Python, JS, and CSS) and skips esbuild if no changes are detected.
  • Added --force flag to tetrabuild management command (via build function update) to bypass incremental build check and perform a full rebuild.

Changed

  • Improved STATIC_ROOT management during builds: it is now only cleared when force=True is used, while individual library directories are still cleaned when they are rebuilt.

[0.7.0] - 2026-01-13

Added

  • AppRouter and Link component for dynamic routing/navigation within a container. (Note: Highly experimental).
  • Support for trailing slashes in routes when Django's APPEND_SLASH is enabled.
  • Support for optional arguments in Router load method.
  • New routing documentation and comprehensive tests.
  • Bundle esbuild within Tetra (auto-download), remove npm dependency.
  • rename decorator @public.subscribe to @public.listen for consistency.

Fixed

  • Memory leak bug when watching files recursively in root directory.
  • Ensure all attributes are set when unpickling a component.
  • Improved handling of conditional node branches for {% slot %} tags.
  • Safely patch Template.compile_nodelist to preserve the original method.

[0.6.10] - 2026-01-10

Added

  • Configurable component module names via settings and constants.
  • mypy added to dev dependencies.
  • Tests for importing Tetra without channels and ReactiveComponent handling.

[0.6.9] - 2026-01-10

Fixed

  • Ensure Tetra is importable without channels when no ReactiveComponent is used.
  • npm install in Makefile.

Changed

  • Use uv run for tests in Makefile.
  • Use publish instead of publish-prod in Makefile.

[0.6.8] - 2026-01-10

Added

  • Loading indicators for buttons now work independently. Each button has its own indicator that only shows while that specific button's action is running. When a button finishes its task, only its indicator turns off, while other buttons' indicators keep running if their tasks are still in progress.
  • Refactored pytest fixtures and test views to be reusable in other packages that use Tetra.

Fixed

  • postpone template compiling to time when all libraries are loaded, so component referrals of not yet loaded components work.

[0.6.7] - 2026-01-06

Added

  • DownloadButton demo component
  • accept dynamic root tags in components (like `<{{ tag }}>) in checks

Removed

  • remove ViewMixin from public API - it's not worth all the problems it creates.

[0.6.6] - 2026-01-05

Added

  • add ViewMixin to allow components to be used as standalone Django views with as_view().
  • include security-filtered GET parameter retrieval in ViewMixin, with automatic injection into load().

Fixed

- fix a bug that prevented the TetraConsumer from working with channels when DEBUG==False

Added

  • allow "page" components to be used as full Django views

[0.6.5] - 2026-01-04

[0.6.3] - 2026-01-04

[0.6.4] - 2026-01-04

Changed

  • introduced some complicated workarounds for websockets not working properly, introducing a few new bugs... pfff..

[0.6.2] - 2026-01-04

Fixed

  • correctly add all js, scripts, staticfiles etc into the pypi package

[0.6.1] - 2026-01-04

Fixed

  • TetraConsumer now is stricter with allowing user and group subscriptions.

Added

  • Code coverage

[0.6.0] - 2026-01-02

Changed

  • BREAKING change: rename tx-indicator to t-indicator HTML class

Fixed

  • build_sh.sh does now produce output code in src/ directory structure.

[0.5.3] - 2025-12-20

Fixed

  • fix "optional" channels dependency blocking tetra when not using channels. Only import channels if websockets are needed in project
  • components in subdir apps are now found correctly by label

Changed

  • change to a src/ based directory structure
  • Django 6.0 compatibility

Changed

  • switch to playwright in ui component testing

[0.5.2] - omitted. Don't ask.

[0.5.1] - 2025-10-03

Fixed

  • use encrypted wss scheme when connecting to server using https
  • some smaller bugfixes

Changed

  • clear static files before building libraries
  • get rid of Blacknoise in demo project

[0.5.0] - 2025-10-02

Changed

  • introduce websocket-enhanced ReactiveComponents

[0.4.0] - 2025-08-04

Changed

  • rename request.tetra.current_url_abs_path to current_url_full_path to better adhere to naming standards. current_url_abs_path is deprecated.
  • BREAKING CHANGE remove the @ tag for component rendering. Use the component name alone.
  • BREAKING CHANGE disable {% <app>.<library>.<component_name> /%} reference. Only allow {% [<library_name>.]<component_name> / %}
  • BREAKING CHANGE rename @v tag to livevar
  • BREAKING CHANGE block inside components renamed to slot
  • refactoring of internal Component and Library methods

Added

  • request.tetra.current_url_path that holds the path without query params
  • a tetra template variable that holds the TetraDetails of a request, or possible equivalents of the current main request.
  • Client URL pushes are now anticipated and reflected on the server before rendering the component on updates

[0.3.1] - 2025-04-19

  • BREAKING CHANGE rename all tetra:* events to kebab-case: before-request, after-request, component-updated, component-before-remove etc. This was necessary because camelCase Events cannot be used properly in x-on: attributes - HTMX attributes are forced to lowercase, which breaks the event capture.

[0.3.0] - 2025-04-18

Added

  • beforeRequest, afterRequest events
  • add support for loading indicators (=spinners)
  • add support for file downloads in component methods

Changed

  • BREAKING CHANGE rename all tetra:* events to camelCase: componentUpdated, componentBeforeRemove etc.

Fixed

  • fix file uploads for FormComponent (using multipart/form-data)

[0.2.1] - 2025-03-29

  • fix a small bug that could early-delete temporary uploaded files

[0.2.0] - 2025-03-27

Added

  • DynamicFormMixin for dynamically updatable FormComponents
  • Improved demo site
  • Added debug logging handler
  • Improved component import error handling
  • Allow component names to be dynamic
  • @v shortcut templatetag for "live" rendering of frontend variables
  • Better support for Django models
  • Experimental FormComponent and ModelFormComponent support with form validation
  • Definable extra context per component class
  • reset() method for FormComponent
  • push_url() and replace_url() component methods for manipulating the URL in the address bar
  • recalculate_attrs() method for calculated updates to attributes before and after component methods
  • request.tetra helper for current_url, current_abs_path and url_query_params, like in HTMX
  • add life cycle Js events when updating/removing etc. components
  • add a special response indicator for Tetra responses.
  • Integration of Django messages into Tetra.
  • <!-- HTML comments --> at begin of components are possible now

Removed

  • BREAKING CHANGE ready() method is removed and functionally replaced with recalculate_attrs()

Changed

  • BREAKING CHANGE: registering libraries is completely different. Libraries are directories and automatically found. The library automatically is the containing module name now. Explicit "default = Library()" ist disregarded.
  • Components should be referenced using PascalCase in templates now
  • Component tags: replace **context with __all__ when passing all context in template tags
  • More verbose error when template is not enclosed in HTML tags
  • Improved component import error handling
  • Improved demo site

[0.1.1] - 2024-04-10

Changed

  • New package name: tetra
  • Add conditional block check within components
  • Update Alpine.js to v3.13.8
  • Switch to pyproject.toml based python package
  • Improve demo project: TodoList component,- add django-environ for keeping secrets, use whitenoise for staticfiles
  • Give users more hints when no components are found
  • MkDocs based documentation
  • Format codebase with Black

Added

  • Basic testing using pytest

Fixed

  • Correctly find components

[0.0.5] - 2022-06-13

Changed

  • This is the last package with the name "tetraframework", transition to "tetra"
  • Provisional Python 3.8 support

Fixed

  • Windows support

[0.0.4] - 2022-06-22

  • Cleanup

[0.0.3] - 2022-05-29

Added

  • _parent client attribute added, this can be used to access the parent component mounted in the client.
  • _redirect client method added, this can be used to redirect to another url from the public server methods. self.client._redirect("/test") would redirect to the /test url.
  • _dispatch client method added, this is a wrapper around the Alpine.js dispatch magic allowing you to dispatch events from public server methods. These bubble up the DOM and be captured by listeners on (grand)parent components. Example: self.client._dispatch("MyEvent", {'some_data': 123}).
  • _refresh public method added, this simply renders the component on the server updating the dom in the browser. This can be used in combination with _parent to instruct a parent component to re-render from a child components public method such as: self.client._parent._updateHtml()

Changed

  • Built in Tetra client methods renamed to be prefixed with an underscore so that they are separated from user implemented methods:
    • updateHtml is now _updateHtml
    • updateData is now _updateData
    • removeComponent is now _removeComponent
    • replaceComponentAndState is now _replaceComponent