# Citry > A fast, simple, and smart frontend framework for Python that brings the best of Vue, React, Django, and Jinja. ## Docs ### Getting started - [Install Citry](https://citry.dev/getting-started/installation/): Install Citry in a Python environment, then render a small component to confirm everything works. - [Your first component](https://citry.dev/getting-started/your-first-component/): Build a reusable card, choose its border color, add some content, and render it with Python. - [Use data in components](https://citry.dev/getting-started/data-in-components/): Give a Citry component typed Python options, show them in its HTML, and turn a list into repeated content. - [Build a page from components](https://citry.dev/getting-started/build-page/): Import your Citry components, use them as tags inside a page, pass Python values to them, and check the rendered result. - [Add flexible content](https://citry.dev/getting-started/add-slots/): Give a Citry component a main content area, a named area, and fallback content that appears when nothing is supplied. - [Add browser behavior](https://citry.dev/getting-started/browser-interactivity/): Use Alpine directives in a Citry component, then pass Python data into component-owned browser code with js_data and $component. - [Connect components in the browser](https://citry.dev/getting-started/client-props-and-handlers/): Pass a reactive browser value into a child Citry component and handle the child's click in its parent. - [Serve a page with FastAPI](https://citry.dev/getting-started/fastapi/): Put a Citry component behind a FastAPI route and connect the browser to Citry's own routes. - [Call Python from a click](https://citry.dev/getting-started/call-python/): Send a click to a Python event handler and show its answer without reloading the page. - [Events state](https://citry.dev/getting-started/state/): Add signed Citry State so Python can load the next set of choices on each call. - [Handle and validate a form](https://citry.dev/getting-started/forms/): Turn named form controls into typed Python data and return a useful field error. - [Replace part of the page from Python](https://citry.dev/getting-started/server-rendered-updates/): Render a new component into one chosen part of the page, including the component's JavaScript and CSS. ### Template syntax - [Expressions](https://citry.dev/syntax/expressions/): How Citry's {{ }} expression syntax works, which Python is allowed, why builtins like len() are missing, and how expression comments behave. - [Dynamic attributes](https://citry.dev/syntax/dynamic-attributes/): Use c- attributes to compute attribute values from expressions, with boolean, class, style, spreading, and literal-colon rules. - [Control flow](https://citry.dev/syntax/control-flow/): Render parts of a template conditionally or repeat them with citry's if/elif/else and for/empty, in both tag and shorthand attribute forms. - [Comments](https://citry.dev/syntax/comments/): The three ways to write comments in citry templates, which ones survive to the rendered HTML, and which are stripped. - [Nested templates](https://citry.dev/syntax/nested-templates/): How a c-* attribute can hold a nested template instead of an expression, and how citry decides which one you meant. ### Concepts - [Components](https://citry.dev/concepts/components/): How a citry component pairs a template with the data it needs, and how you construct, render, and reuse one. - [Client interactivity](https://citry.dev/concepts/client-interactivity/): Use Citry's Alpine runtime, component scopes, client props, boundary handlers, slots, and lifecycle APIs without breaking component isolation. - [Registration and autodiscovery](https://citry.dev/concepts/registration/): How citry finds and registers your components: automatic registration when a class is defined, and autodiscovery of an engine's directories. - [Subclassing components](https://citry.dev/concepts/subclassing/): How a child component inherits or overrides its parent's template, JS, CSS, and dependencies, and how to opt out or reuse parent logic. - [Slots](https://citry.dev/concepts/slots/): Define insertion points in a component and let the caller fill them, with fallbacks, required slots, and scoped data. - [Typing and validation](https://citry.dev/concepts/typing-and-validation/): Declare component inputs with class Kwargs and class Slots so typos and missing or unknown props are caught early rather than in production. - [Rendering](https://citry.dev/concepts/rendering/): How a citry component becomes HTML: the compose, render, and serialize phases, and when to reach past str() for finer control. - [HTML attributes](https://citry.dev/concepts/html-attributes/): Structured class and style values, attribute spreading, and the Python helpers for building attribute dicts. - [Provide and inject](https://citry.dev/concepts/provide-and-inject/): Pass data to a whole subtree of components without threading props through every level in between. - [Error boundaries](https://citry.dev/concepts/error-boundaries/): Wrap a section in c-error-fallback so a render error shows a fallback instead of breaking the page. ### Events - [Server events](https://citry.dev/events/): Call a Python event handler from a Citry component and update the page without reloading it. - [Keep state between calls](https://citry.dev/events/state/): Choose the small values a Citry component carries through the browser and rebuild each event render from explicit inputs. - [Handle and validate forms](https://citry.dev/events/forms/): Turn named form controls into typed Python data and show server validation without losing what the user entered. - [Bind events in templates](https://citry.dev/events/bindings/): Call Citry event handlers from HTML, bind controls to State, and show loading or error feedback with Alpine. - [Update the page from a handler](https://citry.dev/events/actions/): Return Citry event actions in order, render into page targets, and preserve browser state across updates. - [Use event routes directly](https://citry.dev/events/http/): Call Citry event handlers through GET requests, native forms, htmx, and dedicated download responses. ### Advanced - [Dynamic components](https://citry.dev/advanced/dynamic-components/): Choose a component or an HTML tag name at render time with c-component c-is and c-element c-is in citry templates. - [JS and CSS dependencies](https://citry.dev/advanced/js-and-css-dependencies/): How citry collects each rendered component's JS and CSS, passes per-instance data with js_data and css_data, and places it at c-css and c-js. - [Alpine runtime](https://citry.dev/advanced/alpine-runtime/): Configure Citry's owned Alpine runtime, register plugins, deploy client graphs safely, and understand CSP and structural-directive limits. - [HTML fragments](https://citry.dev/advanced/html-fragments/): Render a component as an HTML fragment for HTMX-style swaps, and let citry load its JS and CSS in the browser. - [Performance](https://citry.dev/advanced/performance/): Render the parts of a template that never change once, with Const, and reuse them across renders. - [Caching](https://citry.dev/advanced/caching/): Cache complete component subtrees or named template regions with safe variation, expiry, invalidation, and shared backends. - [Extensions](https://citry.dev/advanced/extensions/): How to hook into Citry's lifecycle, install extensions on a Citry instance, and add extension-provided CLI commands. - [Component hooks](https://citry.dev/advanced/hooks/): Use on_render to replace, post-process, or recover a component's output, and on_dependencies to adjust the JS and CSS tags it contributes. - [Sharing components](https://citry.dev/advanced/share-components/): Define engine-neutral Citry components, publish an explicit library manifest, register it atomically, and use it from templates or Python. - [Testing components](https://citry.dev/advanced/testing/): Test citry components in isolation by giving each test its own Citry instance, then rendering and asserting on the HTML. - [Command line](https://citry.dev/cli/): The citry command: inspect an engine, scaffold a component, list registered components, and run extension commands. ### Guides - [Web frameworks](https://citry.dev/web-frameworks/): Mount Citry on FastAPI, Starlette, Flask, Django, or bare ASGI/WSGI so it can serve component assets, fragments, and server events. - [Troubleshooting](https://citry.dev/guides/troubleshooting/): Debug citry: read the component path in render errors, turn on trace logging, and inspect a component's rendered HTML. - [Hot reload](https://citry.dev/guides/dev-server/): Pick up edits to a component's template, JS, or CSS file on the next render without restarting, using citry watch and the reload helpers. - [Migrate from Component.View](https://citry.dev/guides/migrate-from-component-view/): Port django-components Component.View handlers to typed Citry Events, then split HTTP verbs into named interactions. - [Migrate from django-unicorn](https://citry.dev/guides/migrate-from-django-unicorn/): Move django-unicorn state, actions, validation, and browser calls to explicit Citry State and Events handlers. - [Migrate from Tetra](https://citry.dev/guides/migrate-from-tetra/): Port Tetra public state, server methods, promise calls, and client callbacks to Citry State, Events, and actions. - [Migrate from livecomponents](https://citry.dev/guides/migrate-from-livecomponents/): Port livecomponents in two safe steps, first keeping server-held State, then choosing signed State component by component. - [Events migration parity](https://citry.dev/guides/events-migration-parity/): Compare Component.View, django-unicorn, Tetra, and livecomponents capabilities with Citry Events delivery status. ### About - [Compatibility](https://citry.dev/about/compatibility/): The Python versions, operating systems, and CPU architectures citry runs on, and when building from source needs Rust. - [Benchmarks](https://citry.dev/about/benchmarks/): How citry's rendering performance compares to django-components, Django, and Jinja2, plus the benchmark chart and how to reproduce it. - [Security](https://citry.dev/security/): Protect Citry templates and server events with expression sandboxing, explicit State, CSRF checks, and authorization. ### Release notes - [Overview](https://citry.dev/releases/): Release notes for every version of citry, newest first. - [v0.3.0 (2026-07-28)](https://citry.dev/releases/v0.3.0/): What changed in citry v0.3.0 (2026-07-28). - [v0.2.0](https://citry.dev/releases/v0.2.0/): What changed in citry v0.2.0. - [v0.1.0 (2026-06-30)](https://citry.dev/releases/v0.1.0/): What changed in citry v0.1.0 (2026-06-30). ## Examples - [Overview](https://citry.dev/examples/): Runnable Citry components, each rendered live with its source. ### Components - [Card](https://citry.dev/examples/card/): Build a reusable Card with an input, a slot, and component CSS. - [Slots](https://citry.dev/examples/slots/): Give a component named content areas with useful fallbacks. - [Provide and inject](https://citry.dev/examples/provide-inject/): Share a value with every component in a subtree. - [Error boundary](https://citry.dev/examples/error-fallback/): Show fallback content when one part of a page cannot render. - [Recursion](https://citry.dev/examples/recursion/): Render a tree by letting a component call itself. ### Template syntax - [Control flow](https://citry.dev/examples/control-flow/): Render conditions, loops, and empty states in a Citry template. ### Browser and server - [Tabs](https://citry.dev/examples/tabs/): Ship browser behavior with an accessible Tabs component. - [Form submission](https://citry.dev/examples/form-submission/): Handle a form submission entirely in the browser. - [Fragments](https://citry.dev/examples/fragments/): Load a server-rendered component and its assets on demand. ## Reference - [Overview](https://citry.dev/reference/): The citry public API, by area. - [Component](https://citry.dev/reference/component/): The base class every component subclasses. - [Component introspection](https://citry.dev/reference/component-introspection/): Frozen metadata records for component catalogs, schemas, assets, and extensions. - [Component libraries](https://citry.dev/reference/component-libraries/): Engine-neutral component definitions, explicit manifests, and per-Citry installations. - [Citry instance and config](https://citry.dev/reference/citry/): The Citry instance that scopes components, settings, and caches. - [Rendering](https://citry.dev/reference/rendering/): The three-phase render pipeline and its output structs. - [Slots](https://citry.dev/reference/slots/): The slot value and fill types. - [Nodes](https://citry.dev/reference/nodes/): The runtime node classes the compiled template instantiates. - [Extensions](https://citry.dev/reference/extensions/): The plugin system: the extension base, its commands, and the hook context objects. - [Dependencies](https://citry.dev/reference/dependencies/): The JS/CSS dependency types collected and placed at serialize time, and the built-in citry.ext.dependencies extension that owns them. - [Render cache keys](https://citry.dev/reference/cache-keys/): Exact key helpers and errors for component and named-fragment render caches. - [Events](https://citry.dev/reference/events/): Event handlers declared on components: the class Events: contract, the typed base for it, and the built-in citry.ext.events extension that owns it. - [Browser APIs](https://citry.dev/reference/browser-apis/): Reference for $component, Citry's Alpine magics, and the public Citry browser methods. - [HTML attributes](https://citry.dev/reference/attributes/): Helpers for Vue-like class/style merging on HTML elements. - [Web integration](https://citry.dev/reference/web/): The route table a web framework mounts, and the request/response types handlers use (see citry.contrib). - [Contrib integrations](https://citry.dev/reference/contrib/): Adapters mounting citry into web frameworks, and cache adapters for shared stores (the citry.contrib. modules). - [Built-in tags](https://citry.dev/reference/builtins/): The c-* tags Citry provides in every component template. ## Community - [People](https://citry.dev/community/people/): The people who maintain, have shaped, and contribute to Citry. - [Getting help](https://citry.dev/community/help/): Where to ask questions about Citry, how to search before posting, and where to report bugs and security issues. - [Contributing](https://citry.dev/community/contributing/): How to get involved with citry - report bugs, send fixes, propose ideas, help others, and pick up your first issue. - [Code of conduct](https://citry.dev/community/code-of-conduct/): Citry follows the Contributor Covenant to keep the community welcoming and harassment-free for everyone. - [Development](https://citry.dev/community/development/): Set up citry locally, run the full check gate, rebuild the Rust extension, preview the docs site, and see how CI is layered. - [AI bot policy](https://citry.dev/community/ai-bot-policy/): Which AI training and search crawlers may index the Citry documentation, and why the robots file allows them. - [License](https://citry.dev/community/license/): Citry is free and open source, released under the MIT license. ## Blog - [All posts](https://citry.dev/blog/): Project news, engineering stories, and dated context from the people building Citry. - [Why language-agnostic tools matter](https://citry.dev/blog/language-agnostic-tools/): A shared core can give several language communities the same reliable behavior without forcing them into the same framework.