TDLib owns the protocol, not your key, and its build scripts edit your checkout
Cross-platform library for building Telegram clients
At a glance
- What is it?
- TDLib is the C++ library Telegram clients are built on, with JSON, JNI and C++/CLI interfaces, a CMake build, and a source tree that some build options modify in place. What it hands you is the protocol; key custody, toolchain choice and restore paths stay with the application.
- Who is it for?
- TDLib is the right foundation when you are writing a client that must speak the Telegram protocol correctly and handle reconnection, ordering and local storage for you. It is the wrong choice for a wrapper project or a short deadline, because the build needs a C++17 toolchain with OpenSSL and zlib, the .NET and low-memory paths modify your checkout, and the encryption key lifecycle is entirely yours.
- Can I use it commercially?
- Yes. BSL-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- tdlib/td9,289 ★ · +170
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| tdlib/td | 9.1k | 9.3k |
170 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The encryption key is yours, so the local database is only as recoverable as your key storage
TDLib encrypts all local data using a user-provided encryption key, and in the same breath the feature list says it takes care of network implementation details, encryption and local data storage. Read together, those two claims divide the work: the library handles the mechanism, your application holds the secret.
That division decides how your storage story has to be built. Supplying the key and deciding where it is kept are application code, so the local data is only as recoverable as your own key storage.
`SplitSource.php` rewrites your checkout in place and needs a matching undo
For low memory devices the documentation gives you a script that edits the source tree, then builds only two targets.
php SplitSource.php
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target tdjson
cmake --build . --target tdjson_static
cd ..
php SplitSource.php --undoThe first line and the last line matter as much as anything between them. The script rearranges files in place, so a build you interrupt before the undo step leaves a working copy that no longer matches what you checked out, and every later diff, review and pull carries that noise. There is also a narrower point hiding in the target list. The recipe builds tdjson and tdjson_static, which are the JSON interface libraries. The C++ interface behind Td::TdStatic is not in that list; the README frames the step as compiling only the needed targets.
Building with `TD_ENABLE_DOTNET` strips C++ docs from three headers until you git checkout them
The .NET binding is the one that changes your tree. TDLib exposes a native .NET interface through C++/CLI and C++/CX, turned on with -DTD_ENABLE_DOTNET=ON or -DTD_ENABLE_DOTNET=CX. Then comes the catch: when TDLib is built with that option enabled, C++ documentation is removed from some files, and putting it back means running
git checkout td/telegram/Client.h td/telegram/Log.h td/tl/TlObject.hSo the build is not read-only with respect to your checkout, and the repair step quietly assumes you have one to restore from. Portability is the second limit, and it is stated plainly. .NET Core supports C++/CLI only since version 3.1 and only on Windows, so if you are on an older runtime or need to target more than Windows, the instruction is to use the JSON interface through P/Invoke instead. That is not a free fallback. It means a second integration path, a second marshalling layer, and a second thing to keep working when the C API shifts.
The dependency floor says GCC 7.0 while the memory note measures GCC 4.9
The dependency list is short enough to check a toolchain against by hand. You need a C++17 compatible compiler: Clang 5.0+, GCC 7.0+, MSVC 19.1+ with Visual Studio 2017.7+, or Intel C++ Compiler 19+. Alongside that come OpenSSL and zlib, then gperf and CMake 3.10 or newer for the build itself, and PHP described as optional for documentation generation.
Two things in that list deserve a second look. The declared floor is GCC 7.0, but the memory figures quoted later in the documentation were taken with clang 6.0 and libc++, and with GCC 4.9 and 6.3, where per-file RAM ran from under 500 MB to under 1 GB. The compilers you are told to use are therefore not the compilers those numbers describe, so treat the memory guidance as an order of magnitude rather than a budget. And PHP being optional does not help a machine that follows the low memory recipe, since its first and last commands are both php SplitSource.php. If your build hosts are locked down toolchains, that single dependency decides whether the memory path is available at all.
No GitHub releases, so the version string lives in find_package and CHANGELOG.md
There is no release stream to pin against. The repository publishes no GitHub releases, and version information is scattered across a few places instead: CHANGELOG.md at the root, an update_version.sh script beside it, and a version number written into the documented CMake find call.
find_package(Td 1.8.69 REQUIRED)
target_link_libraries(YourTarget PRIVATE Td::TdStatic)The 1.8.69 in that snippet is the version current when the documentation was written, not a claim about what the default branch holds today, and copying it forward pins you to whatever your package manager resolves. Building from a clone gives you the commit you checked out with no tag to compare it against, so keeping track of drift means reading the changelog and the commit log rather than watching a releases page. For a library that ships the protocol implementation for a client application, that is a workable arrangement with a real cost: before you upgrade you have no mechanical way to tell which client-visible changes landed between two builds.
add_subdirectory or find_package decides who owns your build
Two CMake integration styles are offered and they differ in who drives compilation. The first vendors TDLib into your build:
add_subdirectory(td)
target_link_libraries(YourTarget PRIVATE Td::TdStatic)The second references an installed copy through find_package. Three targets exist across both. Td::TdJson and Td::TdJsonStatic are the dynamic and static forms of the JSON interface, which exposes a simple C interface; Td::TdStatic is a static library with a C++ interface for general use, documented through ClientManager and Client.
The JSON targets matter more than a C interface usually implies. TDLib also ships native Java bindings through JNI, enabled with -DTD_ENABLE_JNI=ON, and the .NET bindings described above, yet the JSON interface is reachable from any language able to execute C functions. That is what makes the multi-language claim practical rather than aspirational.
Sixteen named platforms against nine example directories
The platform list is long and the shipped examples are not. TDLib names Android, iOS, Windows, macOS, Linux, FreeBSD, OpenBSD, NetBSD, illumos, Windows Phone, WebAssembly, watchOS, tvOS, visionOS, Tizen and Cygwin as targets. The example directory in the repository lists nine: android, cpp, csharp, ios, java, python, swift, uwp and web.
Beyond the example directories, which the README says carry detailed build instructions for Java, C# and UWP, the README offers a generic sequence, mkdir build, cd build, cmake -DCMAKE_BUILD_TYPE=Release .. and cmake --build ., plus an external build instructions generator you configure by picking a programming language and a target operating system. The throughput claim has a similar shape: more than 43000 active bots handled simultaneously by a single TDLib instance is stated for the Telegram Bot API, which describes a server deployment and tells you nothing about one interactive client on a phone. Read both numbers as scope markers rather than guarantees for the application you are building.
Editorial conclusion
TDLib is the right foundation when you are writing a client that must speak the Telegram protocol correctly and handle reconnection, ordering and local storage for you. It is the wrong choice for a wrapper project or a short deadline, because the build needs a C++17 toolchain with OpenSSL and zlib, the .NET and low-memory paths modify your checkout, and the encryption key lifecycle is entirely yours. Before starting, decide who holds that key, pick one CMake integration style rather than both, and confirm your platform has a build recipe beyond the generic CMake sequence.
Frequently asked questions
Which database does Telegram use, and how does TDLib store data locally?
TDLib handles local data storage for the client and encrypts all local data using an encryption key the application provides. The source tree carries separate tddb/ and sqlite/ directories alongside the td/ library itself.
What is the TDLib API used for and where is the list of methods?
TDLib is a cross-platform library for building Telegram clients, taking care of network implementation details, encryption and local data storage. The authoritative list of methods and classes is the td_api.tl scheme, with generated HTML documentation linked from the repository.
What language is TDLib written in and which languages can call it?
It is C++ and needs a C++17 compatible compiler, Clang 5.0+, GCC 7.0+, MSVC 19.1+ or Intel C++ Compiler 19+. Any language able to execute C functions can use the JSON interface, Java uses JNI bindings and .NET uses C++/CLI or C++/CX.
Does TDLib publish tagged releases on GitHub that I can pin to?
No, the repository has no GitHub releases. Version information sits in CHANGELOG.md, an update_version.sh script, and the version written into the documented find_package call, and the last push to the repository was on 2026-10-27.
Official sources
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.
[](https://hysenlabs.com/projects/tdlib-td)Star history chart for your README
[](https://hysenlabs.com/projects/tdlib-td)Was this useful?