Library / SDK
Tencent/libpag avatar
Tencent/libpag

libpag shipped v4.4.74 a day after v4.5.98, and the install notes pin a version five minor series behind

The official rendering library for PAG (Portable Animated Graphics) files that renders After Effects animations natively across multiple platforms.

5,819 stars532 forksHTMLNOASSERTION

At a glance

What is it?
A cross-platform renderer for PAG animation files: two parallel release lines that do not order by date, precompiled libraries for five platforms against seven supported at runtime, an Android Gradle snippet pinned to plugin 3.2.1 next to an NDK 28 build requirement, and a licence badge linking to a master branch while the default branch is main.
Who is it for?
libpag is the way to ship After Effects animation inside an app without reimplementing the renderer, and it is worth the dependency if your target is one of the five platforms with precompiled binaries. Four things to check before committing.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • Tencent/libpag5,819 ★ · +28
Star history
Repository2026-09-232026-11-13
Tencent/libpag5.8k5.8k

28 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

v4.4.74 was published a day after v4.5.98

Three recent releases are listed, and they do not sort by date. v4.4.69 came out on 2026-09-03. v4.5.98 came out on 2026-09-17. v4.4.74 came out on 2026-09-18, which is the most recent of the three.

So the highest version number is not the newest release. There are at least two release lines running in parallel, a 4.4 series and a 4.5 series, and a patch is still landing on the older one after the newer one has shipped. The last push to the repository was on 2026-11-02, about six weeks after the last tag.

For anyone automating a dependency update this is the practical problem. A script that resolves to the highest semantic version gets 4.5.98, while a script that takes the most recently published tag gets 4.4.74, and those are different code.

The version numbers are also four components long on the Android side. The Maven coordinate in the install notes carries `4.0.5.10`, four segments where most ecosystems use three, and the current releases are labelled with three. That is not the same numbering scheme as the tag names.

The Android and HarmonyOS instructions pin versions a whole minor series behind

The integration sections name concrete versions, and none of them matches the release feed.

For Android the dependency line is:

code
dependencies {
    implementation 'com.tencent.tav:libpag:4.0.5.10'
}

with an italic note in the surrounding prose saying that `4.0.5.10` should be replaced with the latest release version. The release feed is at 4.5.x, so the documented coordinate is five minor series old and the reader is told to fix it themselves.

For OpenHarmony the dependency is `"@tencent/libpag": "^1.0.1"`, a different numbering line entirely, at version one. For iOS the Podfile entry is `pod 'libpag'` with no version at all, so CocoaPods resolves whatever it considers latest. Three platforms, three different version schemes, and none of the three pinned to the current release.

The Android section also carries a buildscript block whose plugin classpath is `com.android.tools.build:gradle:3.2.1`, together with the instruction to add `mavenCentral()` to the repositories. That block is what a reader copies into `build.gradle` before the dependency line, so the Android Gradle plugin version is set from the document rather than from the project's own configuration.

Two ProGuard rules follow the dependency, and one of them is not about libpag at all:

code
  -keep class org.libpag.** {*;}
  -keep class androidx.exifinterface.** {*;}

The second keeps Android's EXIF interface library, which is what carries image metadata, and the file gives no reason for needing it.

Five platforms ship precompiled, seven are listed as supported

Two lists in the file do not have the same length.

The system requirements name seven runtime targets with version floors: iOS 15.0 or newer, Android 5.0 or newer, HarmonyOS Next 5.0.0(12) or newer, macOS 12.0 or newer, Windows 7.0 or newer, Chrome 69.0 or newer for the web build, and Safari 15.0 or newer for the web build.

The getting started section then says that precompiled libraries are published for five platforms only, naming iOS, Android, macOS, Web and OpenHarmony, and that libraries for the other platforms have to be built from the source. Those other platforms include Windows, which appears in the system requirements with a floor of 7.0, and Linux, which is named in the introduction.

So Windows 7.0 and newer is a supported system with no binary to download, and Linux is named in the introduction as a target the library renders on with no precompiled artefact at all. Anyone targeting desktop Windows is signing up for a source build before they have read a line of the API documentation.

The gap between the two lists is a distribution decision rather than a rendering one. The renderer is described as covering vector and raster animations across all the listed platforms; what is missing on two of them is a packaged build.

Building needs NDK 28 while the documented Gradle plugin is 3.2.1

The build prerequisites are a nine-item list with floors, and several of them are much newer than the runtime floors they produce binaries for.

Xcode 13.0 or newer, GCC 9.0 or newer, Visual Studio 2019 or newer, NodeJS 14.14.0 or newer, Ninja 1.9.0 or newer, CMake 3.13.0 or newer, QT 6.2.0 or newer, NDK 28 or newer with 28.0.13004108 recommended, and Emscripten 3.1.58 or newer.

The pairing that stands out is Android. The runtime floor for Android is 5.0 and the Gradle plugin in the copy-paste block is version 3.2.1. A build environment pinned to NDK 28 and a project file pinned to a Gradle plugin that predates it are two different eras in the same document.

NodeJS and Emscripten sit next to each other with a floor of 14.14.0 and 3.1.58 respectively, and Qt 6.2.0 is a prerequisite even though Qt appears nowhere in the runtime requirements, which suggests the desktop tooling rather than the renderer.

The recommendation attached to all of it is a specific IDE: CLion on macOS. So the documented development path assumes a macOS host with a commercial IDE, a full C and C++ toolchain, a Node toolchain, a browser compiler and an Android NDK.

Every badge points at the master branch while the default branch is main

The licence badge at the top of the README links to `github.com/Tencent/libpag/blob/master/LICENSE.txt`, a path written with `master` in it; the other badges link to the pull requests page, codecov, two workflow files at `actions/workflows/autotest.yml` and `actions/workflows/build.yml`, and the releases page, with no branch in the path.

The branch management section below describes something else. It says the `main` branch carries the ongoing work with the latest features and bug fixes, and that `release/{version}` branches are created periodically from `main`, are fully tested, and afterwards accept only high-priority fixes.

The default branch is `main`, so the licence badge points at a branch name the project does not describe using.

Branch policy itself is worth noting for anyone forking. The model is a single integration branch plus periodic frozen release branches, with the release branch created from main rather than from a previous release branch.

The web build loads libpag@latest and names the downloaded file with a regex that stops at the first dot

The web integration is a single HTML file you can paste anywhere, and it pulls the renderer from a CDN with no version in the path:

html
<canvas class="canvas" id="pag"></canvas>
<script src="https://unpkg.com/libpag@latest/lib/libpag.min.js"></script>
<script>
  window.libpag.PAGInit().then((PAG) => {
    const url = 'https://pag.io/file/like.pag';
    fetch(url)
      .then((response) => response.blob())
      .then(async (blob) => {
        const file = new window.File([blob], url.replace(/(.*\/)*([^.]+)/i, '$2'));
        // Do Something.
      });
  });
</script>

Two details in that block matter more than the rest. The script tag resolves `@latest`, so every page that copies it gets whatever the CDN currently serves, with no way to pin a renderer version from the snippet itself. And the download step is where the file gets its name: the URL is passed through `replace(/(.*\/)*([^.]+)/i, '$2')`, which replaces the path segments and the name up to the first period with that name, leaving the rest of the string in place.

For the sample URL that yields `like.pag`, the file name without its path.

Note also that the CDN package name is `libpag` while the OpenHarmony package is `@tencent/libpag`, so the two ecosystems do not agree on the package name either.

Only the macOS dependency sync is written down, and the tree has two extensionless build files

Third-party dependencies are managed with an external tool called depsync, and the README splits the procedure by platform. For macOS it says to run a script from the project root:

code
./sync_deps.sh

and adds that the script installs the necessary tools and synchronises all the third-party repositories.

The tree is consistent with a vendored dependency model. `DEPS` and `vendor.json` sit at the root as the manifests, `vendor/` holds the sources, and there is an `install_tools.sh` next to `sync_deps.sh` for the tool installation the script performs. Two entries in the top-level listing have no extension and no trailing slash, `build_pag` and `build_vendor`, which makes them files rather than directories even though their names read like commands.

Three points about how this repository is described rather than how it works. No licence is recorded for the project in its metadata, while a `LICENSE.txt` file sits at the root and the first badge links to it. The primary language is recorded as HTML, for a cross-platform renderer whose platform directories are android, ios, mac, win, linux, ohos and web. And the tree carries configuration for coding agents in `.claude/` and `.codebuddy/` beside the usual `.idea/` directory.

The performance numbers in the file are comparative rather than absolute: PAG files are described as decoding ten times faster than JSON files of the same animations and being about fifty percent smaller.

Editorial conclusion

libpag is the way to ship After Effects animation inside an app without reimplementing the renderer, and it is worth the dependency if your target is one of the five platforms with precompiled binaries. Four things to check before committing. The release feed is not monotonic: v4.4.74 was published after v4.5.98, so version comparison is not a publication order and you need to read the tag dates. The written install instructions are far behind, pinning Android to 4.0.5.10 and HarmonyOS to 1.0.1 while releases sit at 4.4.x and 4.5.x. Windows and Linux are listed as supported systems but ship no precompiled library, so they mean building from source against the build prerequisites the README lists. And no licence is recorded for the project even though a LICENSE.txt file sits at the root, so read that file rather than assuming.

Frequently asked questions

What is libpag used for?

It renders PAG, the Portable Animated Graphics file format, in real time on iOS, Android, OpenHarmony, macOS, Windows, Linux and the web. PAG files are produced from Adobe After Effects with the PAGExporter plugin and previewed in the PAGViewer app.

Which platforms does libpag ship precompiled libraries for?

Five: iOS, Android, macOS, Web and OpenHarmony. Libraries for other platforms have to be built from the source, which matters because Windows appears in the system requirements and Linux in the introduction without a precompiled download.

How do you add libpag to an Android project?

Add the dependency to app/build.gradle, with mavenCentral() in the repositories section of the root build.gradle, then add ProGuard rules keeping org.libpag and androidx.exifinterface, and run a Gradle sync. The documented coordinate is com.tencent.tav:libpag:4.0.5.10, which the text says to replace with the latest release version.

What do you need to build libpag from source?

Xcode 13.0+, GCC 9.0+, Visual Studio 2019+, NodeJS 14.14.0+, Ninja 1.9.0+, CMake 3.13.0+, Qt 6.2.0+, NDK 28+ with 28.0.13004108 recommended, and Emscripten 3.1.58+. The recommended environment is CLion on macOS.

Which libpag version should an Android project depend on?

The written instructions pin 4.0.5.10 and ask you to substitute the latest release, and the release feed currently sits on a 4.5 line. Two version lines are publishing at once, since v4.4.74 was released after v4.5.98, so read the tag dates rather than comparing version numbers.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. Tencent/libpag on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tencent-libpag.svg)](https://hysenlabs.com/projects/tencent-libpag)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/tencent-libpag.svg)](https://hysenlabs.com/projects/tencent-libpag)

Was this useful?