Skip to content

feat: add Jetpack Compose support with real-time string updates#329

Merged
andrii-bodnar merged 5 commits intocrowdin:masterfrom
leo-benz:feature/compose-support
Apr 2, 2026
Merged

feat: add Jetpack Compose support with real-time string updates#329
andrii-bodnar merged 5 commits intocrowdin:masterfrom
leo-benz:feature/compose-support

Conversation

@leo-benz
Copy link
Copy Markdown
Contributor

@leo-benz leo-benz commented Dec 7, 2025

Summary

This PR adds comprehensive Jetpack Compose support to the Crowdin Android SDK, enabling real-time translation updates in Compose-based applications through a Kotlin compiler plugin.

Key Features

1. Kotlin Compiler Plugin (crowdin-compiler-plugin/)

  • Transparently intercepts stringResource() calls at compile-time
  • Redirects them to crowdinString() for real-time updates
  • Uses K2-compatible IR transformation APIs
  • Includes comprehensive test framework with test generation

2. Gradle Plugin (crowdin-gradle-plugin/)

  • Seamlessly integrates the compiler plugin into Android builds
  • Must be applied before the Compose plugin to ensure correct transformation order
  • Zero configuration required for basic usage

3. Compose Runtime Integration (crowdin/src/main/java/com/crowdin/platform/compose/)

  • ComposeStringRepository: Thread-safe state management for Compose strings
  • crowdinString(): Composable functions with automatic recomposition on translation updates
  • Full WebSocket integration for real-time preview
  • Lifecycle-aware watcher registration/deregistration using DisposableEffect

4. Enhanced WebSocket Support

  • Extended EchoWebSocketListener to support Compose watchers
  • Real-time synchronization between Crowdin platform and app UI
  • Automatic subscription/unsubscription based on composition lifecycle

5. Build Configuration Improvements

  • Centralized version management in gradle.properties
  • Shared publishing configuration (gradle/publishing.gradle.kts) for consistent POM metadata
  • Maven Central ready: Complete POM metadata with sources JARs for all modules
  • Fixed deprecation warnings: Updated buildConfig configuration
  • No code duplication: Single source of truth for versions and metadata

Documentation

  • Added comprehensive documentation in website/docs/advanced-features/jetpack-compose.mdx
  • Code samples for configuration and usage
  • Updated sidebar navigation

Breaking Changes

None - this is a purely additive feature that's opt-in via configuration.

Usage Guide

Option 1: With Compiler Plugin (Recommended)

The compiler plugin automatically transforms all stringResource() calls to support real-time updates. No code changes required!

  1. Apply the Gradle plugin:
plugins {
    id("com.crowdin.platform.gradle")  // Must be before Compose plugin
    id("org.jetbrains.kotlin.plugin.compose")
}
  1. Enable in Crowdin config:
Crowdin.init(
    context,
    CrowdinConfig.Builder()
        .withRealTimeComposeEnabled(true)
        .build()
)
  1. Use existing Compose code - it just works:
@Composable
fun MyScreen() {
    // stringResource() is automatically transformed to crowdinString()
    val text = stringResource(R.string.welcome)
    Text(text = text)
}

Option 2: Without Compiler Plugin

If you prefer not to use the compiler plugin, you can manually use crowdinString():

@Composable
fun MyScreen() {
    val text = crowdinString(R.string.welcome)
    Text(text = text)
}

🤖 Generated with Claude Code


Note

Introduces a K2 compiler plugin and Gradle plugin to auto-transform stringResource() to crowdinString(), plus SDK-side Compose runtime/state + WebSocket integration, centralized build/publishing config, and documentation.

  • Compose Real-time Support (SDK):
    • Add com.crowdin.platform.compose runtime: ComposeStringRepository and crowdinString() composables with stateful updates and lifecycle-aware watchers.
    • Extend Crowdin, CrowdinConfig, and FeatureFlags to enable/guard real-time Compose (API 24+), expose repository, and trigger updates on config/data changes.
    • Integrate WebSocket: enhance EchoWebSocketListener and RealTimeUpdateManager to subscribe/update Compose watchers.
  • Kotlin Compiler Plugin (crowdin-compiler-plugin/):
    • K2 IR transformer replaces androidx.compose.ui.res.stringResource() calls with com.crowdin.platform.compose.crowdinString().
    • Command-line processor/registrar with enabled option; tests and generators included.
  • Gradle Plugin (crowdin-gradle-plugin/):
    • Wires compiler plugin into builds; enforces being applied before Compose; per-variant enablement via crowdin extension.
  • Build/Publishing:
    • Centralize versions/metadata (gradle.properties, libs.versions.toml).
    • Shared POM config (gradle/publishing.gradle.kts) and sources JARs; include new modules in settings.gradle.
    • Add Compose deps/build features in crowdin/ and update example app config.
  • Docs:
    • New Jetpack Compose guide with config/usage; sidebar updated.

Written by Cursor Bugbot for commit ff67778. This will update automatically on new commits. Configure here.

Copilot AI review requested due to automatic review settings December 7, 2025 21:09
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces comprehensive Jetpack Compose support to the Crowdin Android SDK, enabling real-time translation updates in Compose applications through a sophisticated compiler plugin architecture and runtime integration system.

Key Changes

  • New compiler plugin module (crowdin-compiler-plugin) that transparently transforms stringResource() calls to crowdinString() at compile-time using K2-compatible IR transformation
  • New Gradle plugin module (crowdin-gradle-plugin) that integrates the compiler plugin into Android builds with variant-based control
  • Compose runtime integration with thread-safe state management, WebSocket support for real-time updates, and lifecycle-aware watcher registration

Reviewed changes

Copilot reviewed 44 out of 44 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
website/sidebars.ts Added Jetpack Compose documentation to sidebar navigation
website/docs/advanced-features/jetpack-compose.mdx Comprehensive documentation for Compose integration with usage examples
website/docs/advanced-features/real-time-preview.mdx Added cross-reference to Compose documentation
website/docs/code-samples/jetpack-compose/config.kt Configuration example for enabling Compose support
website/docs/code-samples/jetpack-compose/usage.kt Usage example for manual Compose integration
settings.gradle Added new compiler and Gradle plugin modules to build
gradle/publishing.gradle.kts Shared publishing configuration for consistent Maven Central metadata
gradle/libs.versions.toml New version catalog with centralized dependency versions
gradle.properties Centralized version management and publishing metadata
example/build.gradle Enabled Compose support in example app
crowdin/build.gradle Added Compose dependencies and enabled Compose build features
crowdin/src/main/java/com/crowdin/platform/Crowdin.kt Added Compose repository initialization and integration hooks
crowdin/src/main/java/com/crowdin/platform/CrowdinConfig.kt Added configuration flag for Compose support
crowdin/src/main/java/com/crowdin/platform/compose/CrowdinCompose.kt Composable functions for real-time string retrieval
crowdin/src/main/java/com/crowdin/platform/compose/ComposeStringRepository.kt Thread-safe state management for Compose strings with WebSocket integration
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/EchoWebSocketListener.kt Extended WebSocket listener to support Compose watchers
crowdin/src/main/java/com/crowdin/platform/realtimeupdate/RealTimeUpdateManager.kt Integrated Compose repository into real-time update system
crowdin/src/main/java/com/crowdin/platform/data/model/TextMetaData.kt Added resourceId field for Compose integration
crowdin/src/main/java/com/crowdin/platform/util/FeatureFlags.kt Added Compose feature flag
crowdin/src/test/java/com/crowdin/platform/compose/ComposeStringRepositoryTest.kt Basic unit tests for Compose repository
crowdin/src/test/java/com/crowdin/platform/RealTimeUpdateManagerTest.kt Updated tests to include Compose repository parameter
crowdin/src/test/java/com/crowdin/platform/EchoWebSocketListenerTest.kt Updated tests to include Compose repository parameter
crowdin/src/test/java/com/crowdin/platform/FeatureFlagTest.kt Added test for Compose feature flag
crowdin/src/test/java/com/crowdin/platform/CrowdinConfigTest.kt Added test for Compose configuration
crowdin-gradle-plugin/build.gradle.kts Build configuration for Gradle plugin with Maven publishing
crowdin-gradle-plugin/src/main/kotlin/com/crowdin/platform/gradle/CrowdinGradlePlugin.kt Gradle plugin that applies compiler plugin with variant-based enabling
crowdin-gradle-plugin/src/test/kotlin/com/crowdin/platform/gradle/CrowdinExtensionTest.kt Tests for Gradle plugin extension
crowdin-compiler-plugin/build.gradle.kts Build configuration for compiler plugin with test framework
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinComponentRegistrar.kt Compiler plugin entry point and extension registration
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinCommandLineProcessor.kt Command-line processor for compiler plugin options
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinIrGenerationExtension.kt IR generation extension with plugin ordering enforcement
crowdin-compiler-plugin/src/main/kotlin/com/crowdin/platform/compiler/CrowdinStringResourceTransformer.kt IR transformer that intercepts and transforms stringResource calls
crowdin-compiler-plugin/testData/box/stringResourceTransform.kt Compiler plugin test for transformation verification
crowdin-compiler-plugin/test-fixtures/* Test infrastructure for compiler plugin testing
crowdin-compiler-plugin/resources/META-INF/services/* Service loader files for compiler plugin discovery

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@leo-benz leo-benz force-pushed the feature/compose-support branch from b7c33cd to 50c7142 Compare December 7, 2025 21:24
@andrii-bodnar
Copy link
Copy Markdown
Member

@leo-benz thanks a lot for such a great contribution! 🚀

Requesting a review from @MykhailoNester. In the meantime, could you please take a look at the AI comments? If something looks irrelevant, just resolve it.

@leo-benz leo-benz force-pushed the feature/compose-support branch from ff7b804 to 1cb42d6 Compare December 13, 2025 14:33
@leo-benz leo-benz force-pushed the feature/compose-support branch from 1cb42d6 to ff67778 Compare December 13, 2025 14:47
@leo-benz
Copy link
Copy Markdown
Contributor Author

@andrii-bodnar First time for me working with a GitHub repo with such extensive AI checks, overall a nice workflow and good comments 👍🏻 I have addressed and resolved all the relevant ones.

@andrii-bodnar
Copy link
Copy Markdown
Member

Hi @leo-benz, could you please rebase the current branch? There is a conflict in the crowdin/build.gradle file. Please also take a look at the comments above. Thank you!

@leo-benz leo-benz force-pushed the feature/compose-support branch from ff67778 to d4cdd4f Compare March 14, 2026 15:52
@cursor
Copy link
Copy Markdown

cursor bot commented Mar 14, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@leo-benz leo-benz force-pushed the feature/compose-support branch from d4cdd4f to 6585e95 Compare March 14, 2026 18:39
@leo-benz leo-benz force-pushed the feature/compose-support branch from 6585e95 to e00ed41 Compare March 14, 2026 18:58
@leo-benz
Copy link
Copy Markdown
Contributor Author

Rebased and addressed the remaining comments

@andrii-bodnar
Copy link
Copy Markdown
Member

@leo-benz thank you!

There is a failing build pipeline. Could you please take a look?

Copilot's analysis result

The failure is caused by errors from the D8/R8 tool when parsing Kotlin metadata. The logs show:

  • "An error occurred when parsing Kotlin metadata..."
  • "This normally happens when using a newer version of Kotlin than the Kotlin version released when this version of R8 was created."
  • The Gradle task :crowdin:ktlint fails, causing the build to stop.

Solution Steps:

  1. Check Kotlin and R8/D8 versions:
    Ensure the Kotlin version used in your project is compatible with the R8/D8 version bundled in your Android build tools. If they're mismatched, errors like these appear.

  2. Update build tools and dependencies:

    • Update the Android Gradle Plugin to the latest version.
    • Update Kotlin to the latest stable version, or downgrade Kotlin to match the version supported by your build tools.
  3. Pin compatible versions:
    In your project's build.gradle files, set compatible versions. For example:

    // Top-level build.gradle
    buildscript {
        ext.kotlin_version = '1.7.10' // Example, match AGP support
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath "com.android.tools.build:gradle:7.4.0" // Example, use latest stable
        }
    }
    • If your project uses a custom R8 version, update it as well:
    dependencies {
        // If you override R8; otherwise, AGP handles it.
        classpath 'com.android.tools:r8:8.1.56' // Example version, match Kotlin compatibility.
    }
  4. Clean build cache:
    After updating versions, run:

    ./gradlew clean
  5. Verify workflows:
    Make sure your .github/workflows/basic.yml and related CI scripts install compatible JDK, Kotlin, and build tools.

Summary:
Update or align your Kotlin and Android build tools (R8/D8) versions. This resolves unexpected metadata errors during builds.

If you need precise build.gradle changes, please provide your current versions or gradle files.


Will the Jetpack Compose feature require changes to the release process, or can it be handled via the existing release pipeline with JitPack? Thank you!

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 29, 2026

Codecov Report

❌ Patch coverage is 39.63636% with 166 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.58%. Comparing base (42a8e61) to head (d68c656).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...n/platform/realtimeupdate/EchoWebSocketListener.kt 14.71% 56 Missing and 2 partials ⚠️
...ava/com/crowdin/platform/compose/CrowdinCompose.kt 0.00% 55 Missing ⚠️
...rowdin/platform/compose/ComposeStringRepository.kt 68.30% 32 Missing and 7 partials ⚠️
...wdin/src/main/java/com/crowdin/platform/Crowdin.kt 9.10% 9 Missing and 1 partial ⚠️
...n/platform/realtimeupdate/RealTimeUpdateManager.kt 33.34% 1 Missing and 1 partial ⚠️
...rc/main/java/com/crowdin/platform/CrowdinConfig.kt 92.31% 0 Missing and 1 partial ⚠️
...ain/java/com/crowdin/platform/util/FeatureFlags.kt 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             master     #329       +/-   ##
=============================================
+ Coverage          0   55.58%   +55.58%     
- Complexity        0      433      +433     
=============================================
  Files             0       59       +59     
  Lines             0     2055     +2055     
  Branches          0      378      +378     
=============================================
+ Hits              0     1142     +1142     
- Misses            0      676      +676     
- Partials          0      237      +237     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@andrii-bodnar andrii-bodnar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrii-bodnar andrii-bodnar merged commit a654ec2 into crowdin:master Apr 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants