Library / SDK
Tencent/libpag avatar
Tencent/libpag

Tencent/libpag: rendering PAG animations across iOS, Android, Web and OpenHarmony

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

5,794 stars531 forksHTMLNOASSERTION

At a glance

What is it?
libpag is the runtime half of Tencent's PAG format: designers export animations from After Effects with the PAGExporter plugin, and this library plays them back on eight target platforms. The pitch is a smaller binary than JSON and broader AE feature coverage than vector-only pipelines.
Who is it for?
Adopt libpag if your animation pipeline already lives in After Effects and you need one exported file to play identically on mobile and web, since the README states precompiled libraries ship for iOS, Android, macOS, Web and OpenHarmony. Do not adopt it if you want a library you can build from a single toolchain on day one: Windows and Linux are source builds only, and the repository layout shows a CMake project that pulls vendored dependencies.
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 September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem libpag solves: one animation file, many runtimes

Most teams that ship motion design hit the same wall. A designer builds something in After Effects, and the engineering side has to reproduce it per platform: a Lottie JSON on iOS, a different player on Android, a sprite sheet on web. Every runtime drifts. libpag is Tencent's answer to that, and it is deliberately split in two. PAG is a file format for recorded animations, produced by the PAGExporter plugin inside After Effects and previewed in the PAGViewer desktop app, both available for macOS and Windows. libpag is the library that decodes and renders those files at runtime.

The README names the target audience indirectly but clearly: the format is used in WeChat, Mobile QQ, Honor of Kings, Tencent Video and QQ Music, and the README states it is used in thousands of third-party apps. That is a mobile-first, high-traffic context. The concrete claims are narrower than the marketing around them. The README says PAG files decode 10 times faster than JSON files and are about 50 percent smaller for the same animation. Those are the project's own numbers, not independently reproduced here, and they compare against JSON rather than against a specific named player.

What actually differentiates the format is feature coverage. The README states that other solutions may only support exporting limited vector-based AE features, while PAG combines vector and raster exporting so third-party plugin effects in After Effects can be exported too. That is the real argument: not speed, but not having to tell a designer no.

How libpag renders a PAG file at runtime

The architecture visible in the repository is a C++ core with thin platform bindings. The top-level layout has src/, include/, tgfx/, and then one directory per target: android/, ios/, mac/, win/, linux/, ohos/, web/. The tgfx/ directory is a separate graphics abstraction layer that the renderer sits on, which is how the same drawing code reaches Metal on Apple platforms, OpenGL or Vulkan elsewhere, and WebGL in the browser. The web/ directory holds the Emscripten build that produces the JavaScript bundle.

On the authoring side, the flow runs one way. A designer exports from After Effects via PAGExporter into a .pag binary. That file carries the layer tree, keyframes, vector shapes and any embedded bitmaps or audiovisual media, which the README notes can live in a single file without additional attachments. At runtime the library parses that binary, builds the composition, and drives it from a clock. The README describes editing APIs that let developers modify the layer structure of a single PAG file, combine multiple PAG files into one composition, or replace text and images while keeping the pre-designed animation effects. That last capability is what makes video-template style features tractable: the motion is authored once, and the app swaps in content.

The repository also contains a spec/ directory and a pagx/ directory, alongside cli/ and tools/. The presence of a spec folder suggests the binary format is documented rather than reverse-engineered, which matters if you ever need to inspect a file outside the official tooling. The README does not describe the binary layout itself.

Installing libpag and rendering your first PAG file on the web

The README is explicit that precompiled libraries are published only for iOS, Android, macOS, Web and OpenHarmony. Everything else, including Windows and Linux, is built from source. Start with the web path if you want the shortest route to seeing something move, because it needs no package manager at all. Drop this into an HTML file and open it in a browser:

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>

The README's own example stops at the comment, so it hands you a loaded File object and leaves the rest to the Web SDK guide in web/README.md. Note the browser floor: Chrome 69.0+ and Safari 15.0+. That Safari requirement is not incidental, it reflects what the renderer needs from the platform.

On iOS the integration is a CocoaPods dependency. Add the pod to your Podfile:

bash
pod 'libpag'

Then run pod install and import the headers with #import <libpag/xxx.h>. The README lists iOS 9.0+ as the floor. On Android, add mavenCentral() to the repositories block in the root build.gradle, then declare the dependency in app/build.gradle:

bash
implementation 'com.tencent.tav:libpag:4.0.5.10'

The README warns that 4.0.5.10 should be replaced with the latest release version, and it adds a ProGuard rule for org.libpag and androidx.exifinterface. Skipping that rule is a common way to get a build that compiles and then fails at runtime. On OpenHarmony the package manager is OHPM:

bash
ohpm install @tencent/libpag

HarmonyOS Next 5.0.0(12)+ is the stated floor. On all three native platforms, the actual usage pattern is the same as the web one: initialize the library, load a .pag file, attach it to a view, and let the composition play.

Where libpag is the wrong choice

The most obvious limitation is authoring lock-in. A PAG file comes out of After Effects through the PAGExporter plugin. If your motion design happens in Figma, Rive, or hand-written code, libpag has nothing to offer you, because the format is the product and the format is produced by that plugin. There is no documented path in the README for generating PAG files from anything else.

The second limitation is platform coverage versus effort. Windows and Linux are listed in the introduction as supported platforms, but the Getting Started section says precompiled libraries exist only for iOS, Android, macOS, Web and OpenHarmony, and that other platforms must be built from source. The repository layout supports this reading: there is a CMakeLists.txt, a DEPS file, a vendor.json, a sync_deps.sh and an install_tools.sh, which together describe a build that pulls third-party dependencies before it can compile. For a Linux server-side rendering job, that is a real setup cost the README does not walk you through.

The third is a documentation gap rather than a design flaw. The README points to pag.io for the full docs and to separate API references per platform, but it does not document a rollback story, a version compatibility matrix between PAGExporter output and libpag runtime versions, or what happens when a file exported by a newer plugin is loaded by an older library. If you pin a runtime version and your designers update their plugin, that interaction is yours to test. The README is silent on it.

Finally, the license file is present as LICENSE.txt and the badge in the README says Apache 2, but the repository metadata reports the license as NOASSERTION. Before shipping in a commercial product, read LICENSE.txt rather than the badge.

libpag compared with Lottie and SVGA

The closest comparison is Lottie, and the difference is in what gets exported. Lottie is a JSON vector format. Its ecosystem is broader and its tooling is not tied to one company, which is why it shows up in so many cross-platform projects. The trade-off is coverage: vector-only pipelines cannot express arbitrary raster effects, so a designer using a third-party After Effects plugin effect often has to flatten it to a bitmap or drop it. The README positions PAG directly against that, claiming it combines vector and raster exporting so plugin effects survive the export. It also claims the binary is about 50 percent smaller and decodes 10 times faster than the equivalent JSON. If your animations are simple vector shapes, Lottie's larger ecosystem is probably worth more than PAG's size advantage.

SVGA is the other name that comes up, and it sits closer to PAG in spirit: a binary animation format with an After Effects export path. The README does not mention SVGA at all, so any comparison beyond that is outside what this material supports.

A third option is not a format at all: shipping video. For a one-off marketing animation, an MP4 is smaller, universally playable and needs no runtime. libpag earns its place when the animation has to respond to state, when text and images must be swapped at runtime, or when the same asset has to render crisply at multiple resolutions. The README's editing APIs are the dividing line here, since a video cannot do any of that.

Release cadence, branch model and upgrade cost

The release history shows a high-frequency cadence. Three releases appear in the recent list: v4.5.98 on 2026-09-17, v4.4.74 on 2026-09-18, and v4.5.94 on 2026-09-03. Two of those are on the 4.5 line and one on 4.4, which implies parallel maintenance of at least two minor versions. The last push to the repository was on 2026-09-22, the same day as this assessment, so the project is under current development rather than dormant.

The README's branch management section explains the model. The main branch is described as the active development branch containing the latest features and bug fixes, and release/ branches are described as stable milestone branches. The truncated text cuts off mid-sentence after "fully teste", so the full stability guarantee is not visible in the README extract. What is clear is the intent: consume release/ tags for production, and treat main as a moving target.

The practical upgrade cost is the exporter-runtime pairing. Because PAGExporter and libpag ship on separate schedules, an animation exported with a newer plugin may use features an older runtime does not implement. The README does not publish a compatibility table, so pinning both sides and testing before a designer updates is the only defensible approach. On the dependency side, the Android artifact is versioned as com.tencent.tav:libpag, and the README's example pins 4.0.5.10 while noting it should be replaced with the latest release, which means version bumps are expected to be routine rather than rare.

On licensing, the README badge and the repository's LICENSE.txt point to Apache 2, while the repository metadata reports NOASSERTION. That discrepancy is worth resolving against the actual file before you rely on it. This is not legal advice; read LICENSE.txt and, if the answer matters commercially, have counsel read it too.

Editorial conclusion

Adopt libpag if your animation pipeline already lives in After Effects and you need one exported file to play identically on mobile and web, since the README states precompiled libraries ship for iOS, Android, macOS, Web and OpenHarmony. Do not adopt it if you want a library you can build from a single toolchain on day one: Windows and Linux are source builds only, and the repository layout shows a CMake project that pulls vendored dependencies. Before committing, verify that the platform you care about appears in the precompiled list, and check which release branch tag corresponds to the version you pin, because main and release/ branches are managed differently.

Frequently asked questions

Which platforms does libpag support?

The README lists iOS, Android, OpenHarmony, macOS, Windows, Linux and the Web, with stated minimums of iOS 9.0+, Android 5.0+, HarmonyOS Next 5.0.0(12)+, macOS 10.15+, Windows 7.0+, Chrome 69.0+ and Safari 15.0+. Precompiled libraries are published only for iOS, Android, macOS, Web and OpenHarmony; the rest are built from source.

How do I install libpag on Android?

Add mavenCentral() to the repositories block in the root build.gradle, then declare implementation 'com.tencent.tav:libpag:4.0.5.10' in app/build.gradle, replacing the version with the latest release. The README also requires a ProGuard rule keeping org.libpag and androidx.exifinterface to prevent incorrect obfuscation.

Does libpag work in a browser without a build step?

Yes. The README's web example loads the library from unpkg with a script tag, calls window.libpag.PAGInit(), fetches a .pag file and wraps the response in a File object. The README's snippet ends there and defers the rest to the Web SDK guide in web/README.md.

What is the difference between PAG and libpag?

PAG is the open-source file format for recorded animations, exported from After Effects with the PAGExporter plugin and previewed in the PAGViewer app. libpag is the real-time rendering library that decodes and plays those PAG files on each target platform.

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)