RepoPilotOpen in app →

alibaba/Tangram-Android

Tangram is a modular UI solution for building native page dynamically including Tangram for Android, Tangram for iOS and even backend CMS. This project provides the sdk on Android.

Mixed

Stale — last commit 5y ago

weakest axis
Use as dependencyMixed

last commit was 5y ago; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 5y ago; no CI workflows detected

  • 4 active contributors
  • MIT licensed
  • Tests present
Show all 7 evidence items →
  • Stale — last commit 5y ago
  • Small team — 4 contributors active in recent commits
  • Concentrated ownership — top contributor handles 78% of recent commits
  • No CI workflows detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/alibaba/tangram-android?axis=fork)](https://repopilot.app/r/alibaba/tangram-android)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/alibaba/tangram-android on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: alibaba/Tangram-Android

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alibaba/Tangram-Android shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 5y ago

  • 4 active contributors
  • MIT licensed
  • Tests present
  • ⚠ Stale — last commit 5y ago
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Concentrated ownership — top contributor handles 78% of recent commits
  • ⚠ No CI workflows detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live alibaba/Tangram-Android repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/alibaba/Tangram-Android.

What it runs against: a local clone of alibaba/Tangram-Android — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in alibaba/Tangram-Android | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 1789 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>alibaba/Tangram-Android</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alibaba/Tangram-Android. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/alibaba/Tangram-Android.git
#   cd Tangram-Android
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of alibaba/Tangram-Android and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alibaba/Tangram-Android(\\.git)?\\b" \\
  && ok "origin remote is alibaba/Tangram-Android" \\
  || miss "origin remote is not alibaba/Tangram-Android (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java" \\
  && ok "examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java" \\
  || miss "missing critical file: examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java"
test -f "examples/src/main/java/com/tmall/wireless/tangram/example/TangramActivity.java" \\
  && ok "examples/src/main/java/com/tmall/wireless/tangram/example/TangramActivity.java" \\
  || miss "missing critical file: examples/src/main/java/com/tmall/wireless/tangram/example/TangramActivity.java"
test -f "examples/src/main/assets/data.json" \\
  && ok "examples/src/main/assets/data.json" \\
  || miss "missing critical file: examples/src/main/assets/data.json"
test -f "examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java" \\
  && ok "examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java" \\
  || miss "missing critical file: examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java"
test -f "examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java" \\
  && ok "examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java" \\
  || miss "missing critical file: examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1789 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1759d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alibaba/Tangram-Android"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Tangram is a modular UI framework for building dynamic native Android pages from JSON data, built on top of vlayout and UltraViewPager. It renders UI components declaratively by parsing card-based layouts (groups of cells) from backend JSON, enabling rapid page construction without hardcoding UI in Java. Monorepo structure: core SDK code under tangram/ package (Card/Cell base classes), legacy tangram package for v2 compatibility, tangram3 package for experimental v3, and examples/ app demonstrating JSON-driven page rendering with RxJava lifecycle bindings. Key layout implementations inherit from vlayout's layout engine.

👥Who it's for

Android developers at Alibaba/Taobao building dynamic e-commerce and app pages who need to push UI changes server-side without app updates, and want reusable card/cell components with minimal boilerplate.

🌱Maturity & risk

ABANDONED — The README explicitly states 'This project is not maintained any more !!!'. While it has ~1.3M lines of Java code and comprehensive examples with instrumented tests, the last meaningful commit is not recent. Not recommended for new production projects.

High risk: project is explicitly unmaintained by Alibaba, dependencies are pinned to gradle:2.2.2 (2016 era), and there is no active issue triage or PR review. Tangram 3.0 remains in beta and incomplete. No security updates or Android API level compatibility guarantees going forward.

Active areas of work

No active development — README warns against using tangram3 package which is on beta. The examples/ folder contains working demos with test assets (data.json, data3.0.json) and instrumented tests for banner, click, exposure, and timer RxJava event handling, but these are frozen.

🚀Get running

git clone https://github.com/alibaba/Tangram-Android.git
cd Tangram-Android
# Open in Android Studio (requires gradle 2.2.2+)
./gradlew build
./gradlew :examples:installDebug  # Install example app on connected device

Daily commands:

./gradlew clean build                    # Build SDK + examples
./gradlew :examples:connectedAndroidTest # Run instrumented tests
# Then deploy examples APK to device and open MainActivity

🗺️Map of the codebase

  • examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java — Application entry point that initializes Tangram SDK, registers custom components, and sets up the rendering environment
  • examples/src/main/java/com/tmall/wireless/tangram/example/TangramActivity.java — Primary activity demonstrating core Tangram functionality—loads JSON data and renders dynamic layouts via the Tangram engine
  • examples/src/main/assets/data.json — Sample Tangram layout specification in JSON format that defines the structure, components, and styling for dynamic UI rendering
  • examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java — Event handling implementation that demonstrates how to integrate custom click listeners and user interactions with Tangram components
  • examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java — Custom ViewHolder pattern implementation showing how to bind data to dynamically rendered UI elements in Tangram layouts
  • build.gradle — Root build configuration that declares project dependencies including vlayout, UltraViewPager, and RecyclerView—foundational for the modular layout system

🛠️How to make changes

Add a Custom View Component

  1. Create a new ViewHolder class extending the base ViewHolder pattern (examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java)
  2. Implement bindData() method to map JSON properties to UI elements (examples/src/main/java/com/tmall/wireless/tangram/example/data/TestViewHolder.java)
  3. Register the component in TangramApplication during SDK initialization (examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java)
  4. Reference the component by type name in your data.json layout specification (examples/src/main/assets/data.json)

Integrate Custom Event Handling

  1. Extend or create a new support module class (similar to SampleClickSupport) (examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java)
  2. Implement event listener interfaces (onClick, onScroll, onError) (examples/src/main/java/com/tmall/wireless/tangram/example/support/SampleClickSupport.java)
  3. Register the support module in TangramApplication or your activity (examples/src/main/java/com/tmall/wireless/tangram/example/TangramActivity.java)
  4. Define event actions in your JSON data to trigger registered handlers (examples/src/main/assets/data.json)

Create a Custom Data Parser

  1. Create a new parser class implementing data transformation logic (examples/src/main/java/com/tmall/wireless/tangram/example/dataparser/SampleDataParser.java)
  2. Parse JSON data and convert it to Tangram layout objects (examples/src/main/java/com/tmall/wireless/tangram/example/dataparser/SampleDataParser.java)
  3. Register the parser with Tangram engine in TangramApplication (examples/src/main/java/com/tmall/wireless/tangram/example/TangramApplication.java)
  4. Supply JSON data following your custom format specification (examples/src/main/assets/data.json)

Set Up Lifecycle-Aware Reactive Subscriptions

  1. Implement LifeCycleProvider in your activity or fragment (examples/src/main/java/com/alibaba/android/rx/lifecycle/LifeCycleProviderImpl.java)
  2. Use LifeCycleHelper to bind subscriptions to activity lifecycle (examples/src/main/java/com/alibaba/android/rx/lifecycle/LifeCycleHelper.java)
  3. Create Observable streams from view events using ViewClickObservable (examples/src/main/java/com/alibaba/android/rx/ViewClickObservable.java)
  4. Subscribe in your activity with automatic cleanup on lifecycle events (examples/src/main/java/com/tmall/wireless/tangram/example/RxTangramActivity.java)

🔧Why these technologies

  • RecyclerView + vlayout — Provides efficient scrolling with modular layout managers for complex, dynamic layouts without rebuilding the entire view hierarchy
  • UltraViewPager — Handles banner/carousel components with smooth scrolling and advanced paging features required for e-commerce UI patterns

🪤Traps & gotchas

  1. Gradle version lock: build.gradle is pinned to gradle:2.2.2 — modern Android Studio may fail; you may need to downgrade or hack the buildscript. 2) Package naming confusion: tangram/ (v2, maintained) vs tangram3/ (v3, beta, unstable) — README explicitly warns against using tangram3. 3) RxJava lifecycle: LifeCycleProvider pattern requires Activity lifecycle callback hookups; forgetting to call lifecycle.onDestroy() causes event stream leaks. 4) No Maven Central: Dependencies loaded from old Sonatype snapshots and jcenter (both sunset/unreliable now). 5) Abandoned state: No CI/CD visible, no branch protection — cloning and building may fail on modern Android SDK versions without SDK-level downgrades.

🏗️Architecture

💡Concepts to learn

  • Card-Cell composite pattern — Fundamental abstraction in Tangram — Cards group related Cells and control layout, Cells are leaf UI units; understanding this hierarchy is essential for extending the framework
  • Virtual layout (VirtualView) — Tangram leverages vlayout's virtual layout engine to efficiently manage hundreds of RecyclerView items with heterogeneous layout types (flow, linear, sticky) without traditional ViewHolder inflation overhead
  • JSON-driven UI rendering — Core feature — UI is declaratively defined in JSON from backend servers, parsed into Card/Cell objects at runtime, enabling zero-deployment UI changes in production apps
  • RxJava Lifecycle management — Example app uses LifeCycleProvider pattern (LifeCycleHelper) to bind reactive streams to Activity lifecycle events, preventing memory leaks and managing event subscriptions across pause/resume cycles
  • Cell reusability control — Tangram allows fine-grained control over when Cells are recycled vs recreated, critical for performance tuning in lists with expensive view initialization or custom state management
  • Custom layout style via JSON — Layouts (padding, spacing, alignment) can be configured from JSON without hardcoding in Java, enabling designers/backend teams to iterate UI without code deployment
  • Hot-reload page composition — Pages are composed entirely from JSON fetched from backend, allowing A/B testing, feature flags, and gradual rollouts of UI changes without app store submissions
  • alibaba/vlayout — Core layout engine that Tangram-Android wraps — implements Flow, Linear, Fix, Sticky card layout logic at RecyclerView level
  • alibaba/UltraViewPager — Page scrolling and carousel component used by Tangram's PageScrollCard for horizontal paging within JSON-driven layouts
  • alibaba/Virtualview-Android — Companion project using lightweight binary protocol instead of JSON for ultra-compact dynamic UI payload delivery in same ecosystem
  • alibaba/Tangram-iOS — iOS equivalent of this SDK with same Card/Cell architecture and JSON DSL for cross-platform dynamic page building
  • facebook/react-native — Conceptual alternative solving dynamic UI problem via JavaScript DSL instead of JSON, dominant modern approach (Tangram predates React Native's maturity)

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add instrumented tests for Tangram core layout and binding logic

The examples/src/androidTest directory contains test infrastructure but lacks comprehensive coverage of core Tangram functionality. The project has test files for RxBannerSupportTest, RxClickSupportTest, and LifeCycleHelperTest, but there are no visible tests for the main Tangram SDK logic (likely in a tangram/ module not shown). Adding tests for cell binding, layout resolution, and dynamic page rendering would catch regressions and improve confidence in the codebase, especially critical given the project is no longer actively maintained.

  • [ ] Create androidTest file for testing core TangramEngine or TangramBuilder class initialization and configuration
  • [ ] Add instrumented tests in examples/src/androidTest/java/com/tmall/wireless/tangram/ to verify cell data binding with various JSON schemas from examples/src/androidTest/assets/testdata.json
  • [ ] Add tests for layout calculation and rendering with vlayout and UltraViewPager integration, verifying different layout types (linear, grid, etc.) produce expected view hierarchies

Document the migration path from Tangram 2.x to 3.x and clarify API changes

The README contains a warning 'Warning please not use class under tangram3 package!' and states 'Tangram 3.0 is developing', but there is no documentation explaining why tangram3 should be avoided, what changed, or when/if migration will be safe. New contributors and users are left confused. Adding a migration guide or deprecation status would reduce support burden and clarify the project state.

  • [ ] Create docs/Migration-Guide-2x-to-3x.md explaining API differences, deprecated classes, and known issues with tangram3 package
  • [ ] Update README.md with a clearer section on project status, version recommendations, and whether tangram3 is experimental or blocked
  • [ ] Add inline code comments in tangram3 package files (if visible in full repo) marking specific classes as @Deprecated or referencing the migration guide

Add GitHub Actions CI workflow for automated testing on Android SDK updates

The build.gradle shows the project uses Gradle 2.2.2 (from ~2016) and manual Maven/JCenter repositories. There is no visible CI configuration file (.github/workflows/). Since the project is no longer actively maintained, automated testing would help catch breakage from Android SDK/Gradle toolchain updates. This would be especially valuable for the example app and instrumented tests.

  • [ ] Create .github/workflows/android-tests.yml to run ./gradlew build and instrumented tests on pull requests targeting multiple Android API levels
  • [ ] Add a workflow step that validates examples/build.gradle and examples/src/androidTest tests pass (using testdata.json and example assets)
  • [ ] Include a linting step checking proguard-rules.pro (examples/proguard-rules.pro) is still compatible with modern R8/Proguard versions

🌿Good first issues

  • Add instrumented tests for Water Flow Card and Draggable Card layouts (examples/src/androidTest/ has BannerTestActivity and RxClickSupportTest patterns but no coverage for these card types)
  • Write API documentation for custom Card subclassing in docs/Tutorial.md — currently only shows JSON DSL, not Java extension points for Card/CellBinder implementations
  • Migrate examples/build.gradle from gradle:2.2.2 to modern gradle plugin version and update AGP to current, then document breaking changes (low risk since project is unmaintained but useful for local dev)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • e8fe44d — Update README-ch.md (longerian)
  • da5e323 — Update README.md (longerian)
  • fa5c2be — update version (skycrown)
  • 2f70c30 — update version (skycrown)
  • 9dbc326 — split tangram module to tangram and tangram3 (skycrown)
  • e551ae9 — update vlayout version (skycrown)
  • aa3f76a — StickyCard support stackable sticky (skycrown)
  • 35c540c — fix viewPager cannot notifyDataSetChanged (skycrown)
  • 6484230 — Fix componentInfo maybe null. (MikeAfc)
  • ee5948b — Fix data parse of banner card which cause recyclerview refresh. (MikeAfc)

🔒Security observations

This project has significant security concerns. The primary issue is that it is explicitly marked as no longer maintained, making it unsuitable for production use without substantial internal maintenance efforts. Additionally, the build toolchain uses outdated dependencies from 2015-2016 with known vulnerabilities and no security patches available. The Gradle plugin (2.2.2) is 8+ years old and should be urgently updated. The use of snapshot repositories and incomplete build configuration adds further risk. For any organization considering using this codebase, a comprehensive security audit, complete dependency overhaul, and active maintenance fork would be essential prerequisites.

  • High · Outdated Gradle Plugin with Known Vulnerabilities — build.gradle - classpath 'com.android.tools.build:gradle:2.2.2'. The build.gradle uses Android Gradle Plugin 2.2.2 which was released in 2016 and contains multiple known security vulnerabilities and bugs. This version is no longer supported and lacks security patches. Fix: Update to the latest stable version of Android Gradle Plugin (currently 7.x or 8.x). Verify compatibility with the project's minimum API level and test thoroughly.
  • High · Outdated Gradle Build Tools Dependencies — build.gradle - classpath dependencies for bintray and maven plugins. Multiple build dependencies are significantly outdated and no longer maintained: gradle-bintray-plugin:1.4 (2016), build-info-extractor-gradle:4.0.0 (2015), and android-maven-gradle-plugin:1.5 (2015). These may contain unpatched security vulnerabilities. Fix: Update to current versions: use Maven Central or Gradle Plugin Portal for publishing. Consider modern alternatives like gradle-maven-publish-plugin or Maven Central's gradle-nexus-staging-plugin.
  • Medium · Insecure Maven Repository Configuration — build.gradle - repositories section with snapshot URLs. The build.gradle includes SNAPSHOT repositories (https://oss.sonatype.org/content/repositories/snapshots/) which may pull unstable, untested, or malicious artifacts. The commented-out JFrog line suggests previous use of less reliable repositories. Fix: Remove snapshot repositories from production builds. If snapshots are needed for development, isolate them to a separate build configuration. Use only stable, signed releases from Maven Central or official repositories.
  • High · Project No Longer Maintained — README.md - top-level warning. The README explicitly states 'Attention. This project is not maintained any more !!!'. This means no security patches, bug fixes, or updates will be provided. Any vulnerabilities discovered in the SDK or its dependencies will remain unfixed. Fix: Do not use this project in production environments. Either maintain a fork internally with regular dependency updates, or migrate to actively maintained alternatives. If continuing to use, conduct thorough security audits and implement strict dependency management.
  • Medium · Incomplete Dependency Declaration in build.gradle — build.gradle - allprojects repositories section. The build.gradle file appears truncated in the provided content ('maven { u' without completion). This incomplete configuration could hide missing security settings or introduce build inconsistencies. Fix: Complete the build.gradle file and ensure all repository configurations are properly defined. Verify all dependencies are explicitly declared with specific versions.
  • Medium · Unsafe HTTP Repository (Potential) — build.gradle - commented line with http:// URL. The commented-out line references 'http://oss.jfrog.org/oss-snapshot-local/' which uses unencrypted HTTP. If this repository was previously used or could be re-enabled, it poses a man-in-the-middle attack risk for artifact downloads. Fix: Ensure all repository URLs use HTTPS. Remove or update any HTTP repository references. Add repository security scanning tools like Dependabot or Snyk to detect compromised dependencies.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · alibaba/Tangram-Android — RepoPilot