Open-source project
Tencent/puerts avatar
Tencent/puerts

Puerts: TypeScript, Lua and Python Scripting for Unity and Unreal

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.

6,215 stars864 forksC++NOASSERTION

At a glance

What is it?
Puerts embeds V8, Node.js, QuickJS or Lua inside Unity, Unreal and .NET so gameplay code can live in TypeScript. The 3.0 Unity release adds a unified ScriptEnv API across three languages, and Puerts.AI pushes an LLM agent into the editor and the runtime.
Who is it for?
Adopt Puerts when your team already writes TypeScript and you want that code running inside Unity or Unreal with typed access to engine APIs, and the Unity 3.0 ScriptEnv path is the one to evaluate first because it is where the multi-language backends and the release cadence sit. Skip it if you need documented cross-language rollback, a stable Unreal API, or a project whose licence you can classify without reading the file.
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 received new commits within the last day.
What is it written in?
Mainly C++, 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 Puerts solves for Unity and Unreal teams

Game logic written directly in C# or C++ means every balance tweak, dialogue branch or UI rule goes through a compile and a deploy. Puerts exists to move that code out of the compiled binary and into a scripting runtime that the engine hosts. The README describes it as a "multi-language scripting solution" for Unity, Unreal and .NET, and the audience is the team that already has JavaScript or TypeScript engineers and wants them editing gameplay rather than waiting on the engine programmers.

The second problem is type safety across the boundary. Calling into UnityEngine or Unreal from a dynamic language usually means stringly-typed lookups and runtime surprises. Puerts generates TypeScript declarations for host engine APIs, so a call like CS.UnityEngine.Vector3 is checked at build time rather than discovered in a crash log. That generation step is the part that distinguishes it from a plain embedded interpreter.

How the ScriptEnv architecture and backends fit together

Unity 3.0 introduces a unified ScriptEnv type. A single C# API surface takes a backend object, and the backend decides which language runtime is underneath. The README shows BackendV8, BackendLua and BackendPython behind the same env.Eval call, and states that the three languages share one API, so swapping a backend is the only change needed to move a project between them. Unreal currently supports JavaScript and TypeScript only, so the multi-language path is a Unity feature.

The runtime choices are packaged as NuGet artifacts: Puerts.V8.Complete, Puerts.NodeJS.Complete, Puerts.QuickJS.Complete, Puerts.Lua.Complete and Puerts.Python.Complete. V8 and Node.js are the heavyweight options, QuickJS is the small one. The README claims high performance through static wrapper generation for performance-critical paths, and cross-platform reflection calls with what it calls zero boilerplate for C# and C++ interop. Those are the project's own claims, not measured numbers; the repository does not publish a benchmark table alongside them.

Puerts.AI sits on top of the same runtime. It ships a Unity Editor Assistant that turns natural language into scripts executed in the PuerTS environment, with access to both UnityEngine and UnityEditor namespaces. It comes in two forms: an in-editor agent window, and an MCP server. The MCP variant is unusual because, per the README, the server runs inside the Unity process rather than as a separate service, and it exposes a single tool whose builtin modules load on demand instead of registering dozens of tools up front.

Installing Puerts in Unity and running a first script

The README points at tagged releases rather than a package manager install line for the engine plugin: Unity_v3.0.3 is the latest Unity tag and Unity_v2.2.3 is marked lts, while Unreal's most recent listed tag is Unreal_v1.0.9. The NuGet packages named in the badges are the runtime artifacts, so a .NET-side consumer would pull one of the Puerts.*.Complete packages. If you are working inside Unity, take the release archive from the tag that matches your engine version.

The first real use is creating an environment and evaluating a string. This is the README's JavaScript example, unchanged:

csharp
using Puerts;
using UnityEngine;

void Start() {
    var env = new ScriptEnv(new BackendV8());
    env.Eval(@"
        const Vector3 = CS.UnityEngine.Vector3;
        const Debug = CS.UnityEngine.Debug;
        let pos = new Vector3(1, 2, 3);
        Debug.Log('Hello from JS! pos = ' + pos);
    ");
    env.Dispose();
}

You should see the position logged through UnityEngine.Debug, with the Vector3 constructed on the scripting side and passed back into C#. The CS prefix is the bridge namespace the README uses throughout. Disposing the environment at the end of the block is shown in every example, including the Lua and Python variants, which suggests environment lifetime is something the caller owns rather than something the plugin manages.

The equivalent Lua and Python snippets differ only in the backend object and the language syntax, so a team evaluating the 3.0 line can compare all three against the same host code. That is the practical payoff of the unified ScriptEnv design: the integration test is written once.

Where Puerts is the wrong choice

Unreal support is the clearest gap. The README states that Unreal currently supports JavaScript and TypeScript only, so any plan that assumes Lua or Python on the Unreal side is not supported by the documentation. The Unreal release badge also points at v1.0.9 while Unity is on 3.0.3, and the README gives no statement about how the two tracks relate or whether Unreal will follow the ScriptEnv design.

Environment lifetime is another sharp edge. Every example creates a ScriptEnv and calls Dispose explicitly. There is no documented guidance in the README on what happens if a script throws inside Eval, whether the environment survives it, or how to roll back a partially applied script. The README is silent on rollback, error recovery and hot-reload semantics, and those are exactly the behaviours a live-ops team needs before shipping.

Finally, the licence. The repository metadata reports NOASSERTION, while the README badge points at BSD 3-Clause and links to the LICENSE file. The badge and the metadata disagree, and the file itself is the only authority. Treat this as something to resolve internally before adoption rather than something the project has settled.

Puerts compared with xlua

The related searches pair Puerts against xlua, and the difference is the language bet rather than the embedding technique. xlua is a Lua binding for Unity: the scripting language is fixed, and the ecosystem you draw on is LuaRocks. Puerts starts from JavaScript and TypeScript, which means npm packages are available to game code, and TypeScript's static checking applies before the script ever reaches the engine.

Unity 3.0 muddies that distinction on purpose. With BackendLua, Puerts can run Lua through the same ScriptEnv API, so a team that wants Lua is no longer forced outside the Puerts integration. The remaining difference is the backend: xlua is a Lua runtime written for Unity, while Puerts routes Lua through its own backend abstraction alongside V8, NodeJS, QuickJS and Python. If your team's skills are Lua-only and you have no interest in npm or TypeScript declarations, xlua remains the narrower and more direct fit. If you want one integration that can host several languages, Puerts 3.0 is the one making that argument.

Maintenance cadence, upgrade cost and licence

The last push to the default branch was on 2026-09-20, two days before this writing, and the repository is not archived. The Unity track is the active one: Unity_v3.0.3 landed on 2026-09-05, Unity_v3.0.2 on 2026-04-01 and Unity_v3.0.1 on 2026-03-04, all carrying PESAPI_VERSION:11. The Unreal badge still points at v1.0.9. Read that as a project whose investment is concentrated on the Unity side.

PESAPI_VERSION is the number to watch when upgrading. All three recent Unity tags declare the same value, which suggests the scripting API surface was stable across the 3.0.x line, but the README does not document what the version means, when it increments, or what a mismatch costs. An engine plugin that changes its scripting API between tags will force a rewrite of game scripts, and nothing in the README describes a compatibility policy or a deprecation window. Budget for reading release notes rather than trusting a version number.

The licence question is unresolved by the metadata: the repository reports NOASSERTION while the README badge says BSD 3-Clause and links to LICENSE. BSD 3-Clause is permissive, but the discrepancy means the file is the only thing worth reading. This is not legal advice; it is a note that the two signals do not agree.

Editorial conclusion

Adopt Puerts when your team already writes TypeScript and you want that code running inside Unity or Unreal with typed access to engine APIs, and the Unity 3.0 ScriptEnv path is the one to evaluate first because it is where the multi-language backends and the release cadence sit. Skip it if you need documented cross-language rollback, a stable Unreal API, or a project whose licence you can classify without reading the file. Before committing, open the LICENSE file, check which PESAPI_VERSION the Unity package you plan to ship declares, and confirm whether Unreal_v1.0.9 is the only Unreal tag you intend to depend on.

Frequently asked questions

Does Puerts support Unreal as well as Unity?

Yes, but not equally. The README states that Unreal currently supports JavaScript and TypeScript only, while the multi-language ScriptEnv path with Lua and Python is a Unity 3.0 feature. The most recent Unreal tag listed is Unreal_v1.0.9, against Unity_v3.0.3 for Unity.

Which scripting languages can Puerts run in Unity?

JavaScript/TypeScript, Lua and Python. Unity 3.0 introduces a unified ScriptEnv architecture where the language is selected by the backend object, shown in the README as BackendV8, BackendLua and BackendPython behind the same Eval call.

What is Puerts.AI and does it need a separate server?

Puerts.AI is a Unity-only layer built on PuerTS that adds a Unity Editor Assistant and an agent framework that can also run at game runtime. The README states the MCP version runs the server inside the Unity process, so there is no separate service to launch.

Official sources

  1. Issues
  2. README
  3. Releases
  4. Tencent/puerts 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-puerts.svg)](https://hysenlabs.com/projects/tencent-puerts)