Skip to content
cccskills
FreePublished on GitHub

jewel-ui

Build desktop interfaces with Jewel components, themes, layouts, icons, and typography. This skill helps choose the right setup for an IntelliJ plugin or standalone Compose Desktop app, while keeping platform logic outside composables.

OriginalShow the original description

Build UI with Jewel components and themes.

JetBrains/intellij-community20,664 stars(GitHub 20,664 + cccskills 0)

Run score Not tested

See how to install

Good for

  • Building a desktop UI with Jewel controls
  • Choosing themes for a plugin or standalone app
  • Loading icons and styling components with Jewel

Files included (12)

  • SKILL.md13.2 KB
  • evals/evals.json2.3 KB
  • references/COMPONENT-SELECTION.md12.8 KB
  • references/COMPONENTS-CATALOG.md5.4 KB
  • references/ICONS.md3.8 KB
  • references/LABEL-RULES.md3.0 KB
  • references/LAYOUT-PATTERNS.md3.6 KB
  • references/STANDALONE-VS-BRIDGE.md2.1 KB
  • references/THEMING-COLORS.md3.5 KB
  • references/THEMING.md2.7 KB
  • references/TYPOGRAPHY.md3.4 KB
  • skill-source.json1.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

<!-- Generated by community/.ai/render-guides.mjs; edit community/.agents/skills/jewel-ui/SKILL.md -->

Jewel UI

Implement UI with Jewel by first selecting the runtime context, then applying the correct theme wrapper, then using Jewel components and icon APIs.

Quick Snippets

Standalone:

IntUiTheme(isDark = false) {
    App()
}

IntelliJ plugin:

SwingBridgeTheme {
    App()
}

Icon loading:

object MyIcons {
    val Settings = PathIconKey("icons/settings.svg", MyIcons::class.java)
}

Icon(key = MyIcons.Settings, contentDescription = "Settings")

Decorated window (standalone, custom title bar):

IntUiTheme(
    theme = themeDefinition,
    styling = ComponentStyling.default().decoratedWindow(
        titleBarStyle = TitleBarStyle.light(),
    ),
) {
    DecoratedWindow(onCloseRequest = ::exitApplication) {
        TitleBar { /* title bar content */ }
        App()
    }
}

Customize the title bar (colors, metrics, and fullscreen-control handling) by passing TitleBarStyle to ComponentStyling.default().decoratedWindow(...), not through IntUiTheme(isDark = ...) alone.

Scope Boundary

This skill covers Jewel's theme wrappers, components, layout, icons, and typography — the Compose side of the UI. It does not cover Compose-in-Swing embedding mechanics. If the user's question is primarily about:

  • Registering ToolWindowFactory / ToolWindow content
  • Instantiating ComposePanel or wiring setContent
  • plugin.xml tool window extensions
  • enableNewSwingCompositing and related compositing/AWT flags
  • LocalComponent and Swing ↔ Compose bidirectional integration

…the correct response is to name jewel-swing-interop explicitly as the skill for that work and stop. Do not walk through ToolWindowFactory / ComposePanel / plugin.xml setup here, even if you know how. You can still state that content inside the ComposePanel must use SwingBridgeTheme (a theming concern, in scope), and defer the rest to jewel-swing-interop.

Classify Runtime Context

Decide runtime before writing code:

  1. IntelliJ Platform plugin: use the Swing bridge (SwingBridgeTheme) and IntelliJ bundled modules.
  2. Standalone Compose Desktop app: use IntUiTheme and standalone Jewel dependencies.

For agent-generated desktop UI prototypes, prefer a Jewel/desktop preview or sandbox when one is available. Choose Material-style mobile previews only deliberately for mobile/Android-targeting prototypes or when the user explicitly wants a mobile device-frame preview; Material styling is not the general desktop default.

If context is unclear, inspect build files and imports first:

  • org.jetbrains.jewel.bridge.theme.SwingBridgeTheme implies plugin context.
  • org.jetbrains.jewel.intui.standalone.theme.IntUiTheme implies standalone context.

Use STANDALONE-VS-BRIDGE.md for dependency and wrapper snippets.

Keep IntelliJ Platform APIs Out Of Composition

Do not leak or access IntelliJ Platform APIs (IJPL) directly or indirectly inside Jewel/Compose composition. Composables must render explicit state and emit events; IntelliJ Platform interaction belongs at the presenter, controller, service, or action boundary.

Avoid calling or indirectly reaching from composition into platform services, application state, registry, action system, project model, PSI, VFS, message bus, disposables, or other platform-owned mutable/thread-bound APIs. This protects recomposition stability, preview/test isolation, and compatibility across IntelliJ Platform updates.

Preferred pattern:

  1. Platform boundary reads/writes IntelliJ state and owns threading/lifecycle concerns.
  2. The boundary maps that platform state into stable UI state for the composable.
  3. Composable renders the state and invokes callbacks.
  4. Boundary handles callbacks and performs platform work outside composition.

If direct or indirect platform access from composition is unavoidable, pass an injected collaborator as a parameter or composition-local dependency that tests can replace with a fake. Keep the collaborator surface minimal and exclude platform objects from stable UI state. Manage threading, read/write actions, disposables, and Compose stability explicitly.

Apply Theming Correctly

Use the simplest valid theme API first:

  1. Standalone quick start: IntUiTheme(isDark = ...).
  2. For advanced standalone configuration, call IntUiTheme(theme = ..., styling = ..., swingCompatMode = ...).
  3. IntelliJ plugin: SwingBridgeTheme { ... }.

When implementing custom standalone themes:

  1. Build ThemeDefinition via JewelTheme.lightThemeDefinition(...) or JewelTheme.darkThemeDefinition(...).
  2. Override text styles using JewelTheme.createDefaultTextStyle() and JewelTheme.createEditorTextStyle().
  3. Pass composed styling through ComponentStyling.default().with(...) (or specialized style builders).
  4. Prefer public API packages; avoid internal/experimental APIs unless explicitly required.

Use THEMING.md for concrete patterns. Use THEMING-COLORS.md for color-palette and semantic-color guidance. Use TYPOGRAPHY.md for text-style guidance and when-to-use rules.

Key Theme-Derived Caches By Theme State

Do not key remember only by JewelTheme.name, a LaF name, or another human-readable label when the cached value is derived from theme data. Colours, metrics, typography, icon data, and Swing defaults can change while the visible theme name stays the same.

Prefer the narrowest correct key:

  1. If the calculation is cheap, skip remember.
  2. If the cached value depends on concrete values, key by those concrete values, such as colours, text styles, metrics, shortcut text, or strings.
  3. If the cached value depends on broad Jewel theme or LaF environment state that is not practical to enumerate, key by JewelTheme.instanceUuid.

Use JewelTheme.instanceUuid as an invalidation token for theme-instance changes, not as a blanket replacement for precise keys. Avoid JewelTheme.name as a proxy for theme state.

Pick the Right Component

Before writing component code, check COMPONENT-SELECTION.md for the when-to-use rule. Jewel implements the JetBrains IntelliJ Platform UI Guidelines — those guidelines constrain which control fits a given interaction, not just which APIs exist.

Most common decisions:

  1. Mutually exclusive pick from 2–4 options → RadioButtonRow under a GroupHeader (label ends with :). Do not use three DefaultButtons.
  2. For multi-select of independent boolean options, use a group of CheckboxRow controls, and use ThreeStateCheckbox for a "select all" parent.
  3. Pick from 5+ options, long labels, or less-frequent setting → ListComboBox / ComboBox.
  4. Use DefaultButton for the primary action in a form or dialog and OutlinedButton for secondary or cancel actions. Never place two DefaultButton controls side by side.
  5. Icon-only buttons → wrap in a Tooltip carrying the action name + keyboard shortcut. Every icon-only control needs one.
  6. Text input → TextField for one-line; TextArea for multi-line / newline-valid content (commit messages, descriptions, code).

Use COMPONENT-SELECTION.md for the full decision tables and LABEL-RULES.md for label-writing conventions.

Build UI With Jewel Components

Use Jewel components from org.jetbrains.jewel.ui.component for IntelliJ-styled UI.

  1. Use Compose layout containers (Row, Column, Box) for composition.
  2. Use Jewel controls (DefaultButton, OutlinedButton, TextField, Checkbox, Tabs, etc.) for interactive primitives.
  3. Access colors and metrics through Jewel theme locals and component styling APIs instead of hardcoded values.

Use local samples as source-of-truth examples:

Use LAYOUT-PATTERNS.md for composition archetypes extracted from those sample apps. Use COMPONENTS-CATALOG.md for component-by-component catalog guidance.

Keep Composables Small And Navigable

Treat composables like any other production code: keep them clean, clear, and as small as practical. Avoid huge composables with deep nesting and mixed responsibilities. Extract sub-composables when a branch, section, row, toolbar, footer, popup, or repeated layout block has a distinct purpose.

Organize files so readers can follow the UI top-down: put public entry-point composables near the top, then the private sub-composables they call in usage order. Keep helper functions, constants, and state-holder glue close to the code that uses them unless project conventions say otherwise.

Reusable composables are APIs. Give public or cross-file reusable composables KDoc that states their purpose, key parameters, slot expectations, and any non-obvious behavior. For high-level API design, use the AndroidX Compose guidance as a reference, adapted for Desktop/Jewel rather than Android-only APIs:

Do not copy those guidelines wholesale into this skill; link to the source so the guidance stays current.

Load Icons The Jewel Way

Use IconKey-based loading for portability across standalone and bridge:

  1. Use PathIconKey(path, iconClass) when icon path is the same across old/new UI.
  2. Use IntelliJIconKey(oldUiPath, newUiPath, iconClass) when paths differ.
  3. Use Icon(key = ..., contentDescription = ...) or Image(iconKey = ...) instead of deprecated raw painterResource.
  4. Use AllIconsKeys for IntelliJ platform icons.

When using AllIconsKeys in standalone apps, make sure IntelliJ icons are on the classpath (recommended: com.jetbrains.intellij.platform:icons).

Use PainterHint only when you need stateful or dynamic paths or runtime icon patching behavior.

When debugging icon-not-found errors, confirm runtime context (standalone vs plugin) before recommending a fix — AllIconsKeys availability and classpath layout differ between the two. Ask the user if context is not clear from the question.

Use ICONS.md for icon patterns and pitfalls.

Source Permalinks

When citing source in responses, prefer master links for always-latest behavior:

Version Discipline

Treat this skill as Jewel-version scoped.

  1. When version matters, check build files (libs.versions.toml, build.gradle.kts) first; ask only if ambiguous.
  2. Validate compatibility against Jewel release notes.
  3. Prefer APIs available in the target version; avoid suggesting newer APIs without stating the minimum version.
  4. If publishing a version-pinned variant of this skill, replace master links with release-tag links.

Implementation Checklist

Before finishing:

  1. Confirm context-specific theme wrapper is correct (IntUiTheme vs SwingBridgeTheme).
  2. Confirm icon code uses IconKey and classpath-friendly resource resolution.
  3. Confirm dependencies match context.
  4. Confirm no unnecessary Material dependency is introduced in standalone flows.
  5. Confirm code compiles with current module and imports.
  6. Confirm composables do not directly or indirectly access IntelliJ Platform APIs; platform interaction stays at the presenter/controller boundary or behind a tiny injected fakeable collaborator.
  7. Confirm large or deeply nested composables are split into clear sub-composables, file order follows top-down usage, and reusable composables have useful KDoc.
  8. Confirm theme-derived remember values are either uncached, keyed by the concrete values they use, or keyed by JewelTheme.instanceUuid when broad theme/LaF state is the dependency; do not key them by JewelTheme.name alone.
  9. For standalone apps, confirm JetBrains Runtime is used (Jewel requires JBR for full font/rendering behavior).

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

actions

FreeSummary

Implement or update IntelliJ `AnAction` classes and their `plugin.xml` registrations. Keep labels and descriptions in message bundles, configure optional icons, and launch suspending work through the event coroutine scope so synchronous action handling does not freeze the IDE.

  • Adding a new IntelliJ action
  • Updating an action's registration or icon
  • Moving action labels into a message bundle
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

Move IntelliJ JPS test modules to Bazel and diagnose failures that occur only under Bazel. The guide helps trace missing dependencies, plugins, test data, and runfiles, then verify the generated target and migrated tests.

  • Migrating a JPS test module to Bazel
  • Diagnosing a test failure that occurs only in Bazel
  • Checking Bazel dependencies and test data wiring
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

code-style

FreeSummary

Write or review Kotlin and Java code in line with IntelliJ project conventions. The guidance covers language choice, formatting, sealed types, threading annotations, and safe handling of control flow exceptions so changes fit the surrounding codebase.

  • Writing a new Kotlin file that follows IntelliJ conventions
  • Reviewing Java code and checking its style guidance
  • Checking formatting, sealed-type handling, or exception handling
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

commits

FreeSummary

Create, amend, or rename IntelliJ commits with messages that follow the project’s ticket and label formats. Keep each commit focused, explain the reason and decision in the body when needed, and pass the message safely through the shell or PowerShell.

  • Writing a message for a change linked to a YouTrack ticket
  • Preparing a commit message for tests, cleanup, or documentation
  • Amending or renaming an existing IntelliJ commit
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

Compare how Python type checkers interpret a code snippet or file. The script runs selected tools, including ty, pyrefly, basedpyright, mypy, and zuban, then produces a Markdown report with verdicts, timings, and each checker's diagnostic output.

  • Comparing type inference for a Python snippet
  • Checking whether a Python expression should be a type error
  • Reviewing differences among Python type checkers
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

Shape Compose Desktop UI code by keeping composables focused on rendering and placing application decisions in presenters or coordinators. Get guidance on state ownership, effects, reusable component APIs, lazy-list keys, animation, and performance for individual UI changes.

  • Separating screen rendering from application decisions
  • Choosing which UI state belongs in composition
  • Structuring effects and coroutine work
JetBrains/intellij-community20.7KUpdated Oct 26, 2026

See all skills by JetBrains

Report a problem with this skill