Documentation — install, VS Code Marketplace, and one-page-per-product reference for each data extension.
Render @Preview composables to PNG outside Android Studio, so AI coding
agents can see what they're changing. Works with Jetpack Compose (Android,
via Robolectric) and Compose Multiplatform Desktop (via ImageComposeScene).
Renders include paused-clock animation captures (GIF or single frame) and opt-in ATF accessibility checks with annotated overlays.
Also renders Android XML resources —
vector drawables, adaptive launcher icons, animated-vector drawables — and indexes the icon
attributes in AndroidManifest.xml so tooling can link manifest lines to the same rendered PNG.
Modules without any matching resources self-no-op, so this comes along for free with the plugin.
-
Agent skills — the
compose-previewandcompose-preview-reviewskill bundles live inyschimke/skills. Point any agent that can fetch a URL at them; each skill is a complete install-and-iterate playbook. Bootstrap a host machine (CLI + skills in one shot) with the installer inyschimke/skills:curl -fsSL https://raw.githubusercontent.com/yschimke/skills/main/scripts/install.sh | bash -
VS Code extension — published to the VS Code Marketplace and Open VSX (for VSCodium / Cursor / Windsurf). Install from inside the IDE: open the Extensions view (⇧⌘X / Ctrl+Shift+X), search Compose Preview, click Install. Source in
vscode-extension/. -
GitHub Actions — composite actions for CI:
install(CLI on$PATH),preview-baselines(push baselines),preview-comment(before/after PR comments),a11y-report(accessibility findings).
The plugin is published to Maven Central — no auth, no PAT.
// <module>/build.gradle.kts
plugins {
id("ee.schimke.composeai.preview") version "0.10.19"
}Working examples: samples/android/build.gradle.kts,
samples/wear/build.gradle.kts,
samples/cmp/build.gradle.kts.
You can apply the plugin dynamically without modifying the project's source code, useful for AI agents on the CLI, in CI, or when exploring the tool without committing changes. The compose-preview CLI ships a bundled Gradle init script and passes it via --init-script on every invocation, so projects that already apply com.android.application / com.android.library / org.jetbrains.compose pick up the preview plugin without an edit to build.gradle.kts:
compose-preview list # scan @Preview annotations
compose-preview render # render every @Preview to PNGFor direct ./gradlew use (e.g., a CI step that needs extra Gradle flags), materialise the same init script once and thread its path through each invocation:
INIT_SCRIPT="$(compose-preview init-script --path)"
./gradlew --init-script "$INIT_SCRIPT" :app:discoverPreviews
./gradlew --init-script "$INIT_SCRIPT" :app:renderAllPreviewsVS Code users: the
Compose Previewextension already auto-injects via--init-scripton every Gradle invocation it makes — no extra setup needed.
The CLI's auto-inject script detects projects that already declare the plugin (either literally as id("ee.schimke.composeai.preview") version "..." or via a gradle/libs.versions.toml alias resolved through alias(libs.plugins.<x>)) and skips the classpath injection for those builds, so mixed setups work without conflicts.
Requires Java 17+, Gradle 8.13+, AGP 8.13.0+ (Android), Kotlin 2.0.21+,
Compose Multiplatform 1.10.3+ (Desktop). The bottom edge of the supported
consumer envelope is exercised on every push by the
agp8-min job against the fixture
under .github/ci/fixtures/agp8-min/;
the project's own build runs on a newer toolchain (see
docs/AGENTS.md).
Source under samples/. Rendered baselines (PNGs and animation
GIFs, regenerated on every push to main) are browsable inline on the
compose-preview/main
branch:
samples:android— phone, font-family showcase, scrolling captures, animation timelines.samples:wear— Wear OS Material 3 Expressive,EdgeButton, tile previews.samples:cmp— Compose Multiplatform Desktop.samples:remotecompose— Remote Compose againstwear-compose-remote-material3.
ATF a11y findings for the same samples are on the
compose-preview/a11y/main
branch.
Real-world PRs opened by AI coding agents that used compose-preview to
verify their changes.
yschimke/meshcore-mobile#36— renders Play Store listing screenshots (phone + 7"/10" tablet) directly fromPlay Store — …@Previewcomposables, replacing hand-crafted PNGs.
Have one to add? Open a PR or an issue.
- Documentation site — installation, VS Code Marketplace, and the per-product data-extension reference.
- How it works — discovery, renderer, caching, project structure, plugin configuration.
- CI install action — pin the CLI on
$PATHin any GitHub Actions job, with version-catalog + Renovate recipes. - Cloud sandbox setup — Claude Code on the web, network allowlist.
- CI workflows —
compose-preview/mainbaselines, PR diff comments. - Development — building plugin, CLI, and extension from source; consuming
-SNAPSHOTbuilds. - Architecture (contributor) — class-by-class map of the four-stage pipeline.
- Releases · Changelog · License (Apache 2.0)
Use .github/workflows/codex-pr-review-reusable.yml to run AI PR review only after preview generation succeeds and with both code + visual context. The reusable workflow supports Codex, Claude, or Gemini based on which API key is configured (exactly one).
This repository wires the reusable workflow in .github/workflows/codex-pr-review.yml using a preview job plus a thin uses: call to the reusable workflow.
To avoid duplicate PR review comments in this repository, .github/workflows/preview-comment.yml is kept manual (workflow_dispatch). Consumer repos can still choose either workflow (or both) based on their needs.
name: PR Review (Codex + Preview)
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
preview:
runs-on: ubuntu-latest
outputs:
preview_status: ${{ job.status }}
steps:
- uses: actions/checkout@v4
- run: ./gradlew :app:renderAllPreviews
- uses: actions/upload-artifact@v4
with:
name: compose-preview-images
path: app/build/compose-previews/renders
- uses: actions/upload-artifact@v4
with:
name: compose-preview-diff-images
path: app/build/compose-previews/diffs
- uses: actions/upload-artifact@v4
with:
name: compose-preview-metadata
path: app/build/compose-previews/**/*.json
codex-review:
needs: [preview]
uses: yschimke/compose-ai-tools/.github/workflows/codex-pr-review-reusable.yml@main
with:
preview_status: ${{ needs.preview.result }}
strict_mode: true
secrets:
codex_api_key: ${{ secrets.CODEX_API_KEY }}
claude_api_key: ${{ secrets.CLAUDE_API_KEY }}
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}- Agent selection is key-driven: set exactly one of
codex_api_key,claude_api_key, orgemini_api_key. - Codex has a built-in default command. Claude/Gemini require
claude_review_command/gemini_review_commandinputs unless you wrap them in your own caller. compose-preview-images: rendered head/PR preview images.compose-preview-diff-images: visual diffs (baseline vs PR/head), if your preview pipeline generates them.compose-preview-baseline: optional baseline images used to generate diffs.compose-preview-metadata: preview index and mapping files (for example: preview id → file path/module).
- Java 21 (
actions/setup-java,JAVA_HOMEfrom the action). - Android SDK (
android-actions/setup-android). compose-preview-reviewskill installation fromyschimke/skills.- Code diff capture (
git diff) plus artifact download for visual review.
- Preview failed/cancelled/skipped: workflow posts a blocked comment and does not run Codex visual review.
- Artifacts missing: workflow posts a blocked comment with “missing context” details.
- Strict mode enabled + blocking findings: reusable workflow fails its check.
- PR branch update (
update_pr_branch, defaulttrue): workflow attempts to commit.codex/review-output/{codex-review.md,codex-review.json}to the PR branch; for fork PRs or restricted tokens it skips with a warning. - No preview diffs available: Codex still reviews code + available preview images and explicitly marks missing visual-diff context.
needs:pattern (shown above): same workflow, same run.workflow_runpattern: trigger a second workflow after preview workflow completion and passpreview_status: successplus artifact names into the reusable workflow call.
## Codex PR Review
### Code findings
- [blocking] `ui/ProfileCard.kt:84` Null-state branch removed; can crash in empty profile payload.
- [warning] `ui/Theme.kt:42` Hard-coded color bypasses design token.
### Preview findings
- [blocking] `ProfileCard_Default.png` text overlaps avatar at 320dp width.
- [warning] `SettingsScreen_Dark.png` contrast drop on secondary action.
### Missing context / blocked checks
- Baseline metadata for `WearSummaryPreview` missing.
- Visual diff for `TabletLandscape` not present in uploaded artifacts.- Intentionally regress a composable (for example, shrink parent width and increase fixed text size to force clipping).
- Run your preview job to regenerate preview images and visual diffs.
- Open/update a PR and confirm:
- Preview job succeeds.
- Reusable Codex workflow runs after preview (
needs/workflow_rungate). - PR comment includes both code and preview findings.
- In strict mode, blocking visual regression findings fail the check.