A Jinja2 component library for creating reusable, production-ready server-rendered UI components in Python.
Install
mkdir -p .claude/skills/jx && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15423" && unzip -o skill.zip -d .claude/skills/jx && rm skill.zipInstalls to .claude/skills/jx
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use this skill for anything Jx — the Python/Jinja2 component library. Covers BOTH (a) library mechanics and integration AND (b) authoring production-ready UI components. Trigger this skill on any mention of Jx, `.jx` files, "Jinja components" in a Python web app context, or requests to build/create UI components for such an app.Key capabilities
- →Load .jx component files from folders
- →Render components into HTML strings
- →Collect CSS and JS assets from component trees
- →Define typed props with default values for components
- →Manage component attributes for root elements
- →Validate component files for errors
How it works
A Catalog loads .jx files from specified folders and renders them into an HTML string, automatically collecting and deduplicating CSS/JS assets from the imported component tree.
Inputs & outputs
When to use jx
- →Create reusable UI components
- →Build server-rendered views
- →Manage UI assets
- →Integrate components into Python apps
About this skill
Jx — Jinja2 component library
Jx is a Python package that lets you build server-rendered UIs from reusable component files (.jx). A Catalog loads components from one or more folders and renders them with explicit imports, typed props, an attrs pass-through, and a per-component CSS/JS asset system.
Mental model
Catalog("components/") ──► loads .jx files
│
├── catalog.render("page.jx", **kwargs) ──► HTML string
│ └── walks the imported component tree
│ └── collects assets (CSS/JS) automatically
│
└── catalog.add_folder(path, prefix="ui") ──► more component sources
A component file has up to four parts (all optional except the template):
{#import "./icon.jx" as Icon #} {# imports — PascalCase aliases #}
{#css card.css #} {# per-component assets #}
{#js card.js #}
{#def title, subtitle="" #} {# typed props with defaults #}
<div {{ attrs.render(class="card") }}>
<Icon name="star" />
<h3>{{ title }}</h3>
{{ content }} {# main slot #}
</div>
Quick reference
Install: uv add jx (or pip install jx).
Create a catalog:
from jx import Catalog
catalog = Catalog("components/", auto_reload=app.debug)
html = catalog.render("page.jx", user=user, title="Home")
Component file:
{#def name, count=0, items: list = [] #}— required props have no default; types are runtime-checked for primitives.{#import "path.jx" as Name #}— alias must be PascalCase. Three flavors: absolute ("button.jx"), relative ("./sibling.jx"), prefixed ("@ui/button.jx").{#css ... #}/{#js ... #}— comma-separated list of files (relative URLs, absolute paths, or full URLs).
Using a component: HTML-tag syntax, PascalCase, props with key="literal" or key={{ expr }}. Booleans support shorthand: <Input required /> is required={{ true }}.
attrs collects every attribute not declared in {#def}. Render onto the root element with {{ attrs.render(class="default") }} — class merges, other attrs override.
Slots for multiple content areas:
{% slot header %}default{% endslot %} {# in component #}
{% fill header %}custom{% endfill %} {# at call site #}
Assets are collected from the whole tree, deduplicated, in import order. Render with {{ assets.render() }} or split via assets.render_css() / assets.render_js(module=True, defer=True).
Validate: jx check myapp.setup:catalog (or path/to/file.py:catalog). Catches missing imports, used-but-not-imported tags, typos with "did you mean".
When to load which reference
The compact summary above is enough for many tasks. Pull a reference file when the user's question is squarely in that area — don't preload them.
| If the user is asking about… | Read |
|---|---|
| Building a UI component (button, card, modal, dropdown, form, table, layout, navigation, accordion, toast, etc.) — design choices, accessibility, native-HTML-first, color mode, when to use JS, the authoring checklist | reference/authoring.md (always pair with reference/patterns.md if the user asks for a specific category we already have a recipe for) |
Copy-paste recipes for buttons, modals (<dialog>), dropdowns (Popover API), form inputs, data tables, sidebar layouts | reference/patterns.md |
Catalog options (jinja_env, extensions, filters, globals, asset_resolver), add_folder prefixes, render vs render_string, introspection (get_signature, list_components), collect_assets | reference/catalog.md |
Component anatomy in depth, prop types and defaults, slot vs content vs prop tradeoffs, naming conventions, the dash-to-underscore rule | reference/components.md |
attrs.render / set / setdefault / add_class / prepend_class / remove_class, class merging rules, forwarding attrs to a child component, conditional attributes | reference/attrs.md |
Declaring CSS/JS, asset URL strategies (relative, absolute, build-tool), collection order, deduplication, asset_resolver for installable packages | reference/assets.md |
Wiring Jx into Flask / Django / FastAPI / htmx, sharing a Jinja env, passing request, CSRF, URL helpers, partial responses for htmx | reference/frameworks.md |
Running jx check, JSON output, programmatic check_all, the VSCode extension (Go-to-Definition, diagnostics, snippets) | reference/tools.md |
Idioms worth remembering
- Component classes first. When you call
attrs.render(class="Card"), the component's own classes are emitted before anything the caller passed. Callers extend; they don't replace. attrsis for HTML elements, not component tags.<Button attrs={{ attrs }} />is the way to forward a parent's attrs into a child component —<Button {{ attrs.render() }} />does NOT work because component tags are preprocessed.- Underscores in attribute names become dashes at render time:
data_user_id→data-user-id,aria_label→aria-label,hx_get→hx-get. Useful fordata-*,aria-*, htmx, Alpine, etc. - Boolean attrs:
Truerenders the attribute name alone (disabled);Falseremoves it entirely. - Auto-reload off in production.
Catalog(auto_reload=False)skips the file-mtime check on every render. _get_random_id(prefix)is a built-in global — useful for components that need stable-but-unique IDs (popovers, label-for, etc.) without forcing the caller to pass one.- Components are fragments. Don't emit
<!DOCTYPE>/<html>/<body>from a leaf component — that belongs to a singlelayout.jx.
When not to use it
- →When the user's question is about authoring checklist details
- →When the user's question is about copy-paste recipes for UI elements
- →When the user's question is about advanced catalog options
Limitations
- →Prop types are runtime-checked only for primitives
- →Component tags are preprocessed, affecting attribute forwarding
- →Component files are fragments and should not emit full HTML document structures
How it compares
This workflow renders server-side UI components with explicit imports and typed props, unlike manual HTML templating.
Compared to similar skills
jx side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| jx (this skill) | 0 | 3mo | No flags | Intermediate |
| add-new-setting-field | 1 | 7mo | No flags | Intermediate |
| python-pro | 23 | 4mo | No flags | Advanced |
| debugging-streamlit | 7 | 5mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
add-new-setting-field
tsukumijima
【設定追加時は必ず参照】KonomiTV に新しい設定 (v-switch/v-select など) を追加する際の必須手順。SettingsStore.ts / Settings.ts / config.py / Settings/*.vue への追加が必要
python-pro
sickn33
Master Python 3.12+ with modern features, async programming, performance optimization, and production-ready practices. Expert in the latest Python ecosystem including uv, ruff, pydantic, and FastAPI. Use PROACTIVELY for Python development, optimization, or advanced Python patterns.
debugging-streamlit
streamlit
Debug Streamlit frontend and backend changes using make debug with hot-reload. Use when testing code changes, investigating bugs, checking UI behavior, or needing screenshots of the running app.
telegram-dev
2025Emma
Telegram 生态开发全栈指南 - 涵盖 Bot API、Mini Apps (Web Apps)、MTProto 客户端开发。包括消息处理、支付、内联模式、Webhook、认证、存储、传感器 API 等完整开发资源。
podcast-generation
microsoft
Generate AI-powered podcast-style audio narratives using Azure OpenAI's GPT Realtime Mini model via WebSocket. Use when building text-to-speech features, audio narrative generation, podcast creation from content, or integrating with Azure OpenAI Realtime API for real audio output. Covers full-stack implementation from React frontend to Python FastAPI backend with WebSocket streaming.
pyzig
atopile
How the Zig↔Python binding layer works (pyzig), including build-on-import, wrapper generation patterns, ownership rules, and where to add new exported APIs.