latex3: the working repository behind LaTeX3 and expl3
The expl3 (LaTeX3) Development Repository
At a glance
- What is it?
- The GitHub home of the expl3 kernel that LaTeX2e now loads at format creation time, with a directory layout that tells you exactly how much of it you are allowed to depend on.
- Who is it for?
- This repository is a working laboratory rather than a package you add to a document, and the directory names are the honest signal about what is safe to use. Code in l3kernel is what a modern LaTeX2e loads for you, l3packages is history, l3experimental is for interfaces still under discussion, and l3trial never reaches CTAN at all.
- 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 18 days ago.
- What is it written in?
- Mainly TeX, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 15, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A repository of material, not a package you install
The name on GitHub is latex3 and the name everywhere else is expl3, which is the naming split that confuses most people who arrive here from a forum thread. The repository description calls it the expl3 (LaTeX3) Development Repository, and the README is careful about the distinction: what lives here is development material, not only the code that becomes the kernel. Test code, documentation and deliberately experimental pieces sit in the same tree.
The one architectural fact that matters more than any feature list is stated in the first paragraph. All of this code runs on top of LaTeX2e. expl3 was designed as the next generation of the TeX macro language, but it did not replace LaTeX2e; it was absorbed into it. That absorption is why the README describes loading behaviour in terms of kernel versions rather than package versions: with a modern LaTeX2e kernel the l3kernel code is loaded during format creation, and only on an older kernel do you reach for the expl3 package to get at it.
The repository is licensed LPPL-1.3c and carries 2,126 stars and 215 forks, with 148 open issues against a project that has been running since well before most of the current contributors arrived. It is developed by The LaTeX Project and was last pushed on 2026-09-25, so it is comfortably within an active development window rather than a preserved archive.
What l3kernel holds versus what l3trial refuses to release
The README's directory descriptions are unusually precise, and reading them in order tells you how much stability you are buying. l3kernel is the code that forms the expl3 kernel and all stable code, which is the only directory whose contents you can reasonably expect to remain put.
l3experimental is code written to sit on top of LaTeX2e in order to experiment with code and interface concepts. The README is direct that the interfaces for these packages are still under active discussion and that parts of this code may eventually be migrated to l3kernel. That is a migration path stated in advance: what you import today from l3experimental can turn up in l3kernel later, under a different name or a different signature.
l3trial is where the sharpest warning lives. The README calls it material under very active development, for potential addition to l3kernel or l3experimental, and states that material in this directory may include potential replacements for existing modules where large-scale changes are under way. It also states plainly that this code is not released to CTAN. So anything you install from CTAN will never contain it, which makes l3trial useful for tracking what is coming rather than for depending on it today.
l3leftovers rounds out the picture: code developed in the past by The LaTeX Project that is not suitable for use in its current form, though parts may later become the basis for new work in l3kernel or l3experimental. Reading a directory that is explicitly labelled unsuitable in its current form is a reasonable way to understand how the project filters ideas.
l3packages is admitted to be history
l3packages is described as code written to be used on top of LaTeX2e to explore interfaces, and the README then concedes in the same bullet that this bundle is now made up of historical material and that the concepts have been migrated to the LaTeX2e kernel. That is worth pausing on, because package indexes and tutorials still point at expl3 code that no longer lives here in the form people remember.
If you go looking in l3packages for the version of a macro you saw in a tutorial, you may find that the concept lives somewhere else entirely, and the repository will not tell you where. The README also mentions xpackages, which holds code being used to inform kernel developments but no longer directly relevant to users. The tree confirms all of these directories exist as siblings: l3experimental, l3kernel, l3leftovers, l3packages, l3trial, plus articles, discussionpapers, support, texmf and xpackages.
articles and discussionpapers are the other underused part of the tree. The README describes articles as discussion of concepts by team members for publication in TUGboat or elsewhere, which means the design rationale for the language exists as prose in this repository rather than only as comments in code.
Continuous integration against the current TeX Live release
The README is short on build instructions and specific about one thing: GitHub Actions runs as the hosted continuous integration service, and for each commit the build status is tested using the current release of TeX Live. For a TeX macro project that is a meaningful choice, because the macro world does not pin a single runtime the way a package manager pins dependencies. TeX Live moves, distributions lag, and a macro collection that only works against one pinned engine is not usable by much of its audience.
The repository tree backs up the tooling story. There is a build.lua and a build-config.lua at the root, which is the LuaTEX-oriented build system rather than a hand-rolled script, and a support directory that the README describes as files for the automated test suite local to the repository. There is also a CONTRIBUTING.md and a texmf directory, so the repository is set up to produce material that could be distributed in TeX Live convention.
Issues for expl3 are tracked on GitHub rather than on a mailing list archive, which the README notes explicitly. For a project with 148 open issues that is a fair amount of accumulated discussion, and it means the tracker rather than the README is where behaviour questions get settled.
Calendar tags instead of semantic versions
The releases here are named after dates, not versions. The three most recent tags are 2026-09-09, 2026-09-09-dev and 2026-08-10, and the third of those was published on 2026-08-17 while the first was published on 2026-09-21. There is no semantic version number to hold on to, and there is no changelog body attached to any of them.
For a repository that ships snapshot material for a language in development, that is a defensible scheme rather than an oversight. A date tag says precisely when the tree was cut, which matters when the consumer is a kernel development team tracking a moving target. It also means the usual question of which release is compatible with which LaTeX2e version has to be answered elsewhere, since the tag carries no compatibility statement.
The dev suffix is also used, with 2026-09-09-dev published earlier on the same day as 2026-09-09, which suggests a short-lived intermediate cut. If you are pinning expl3 material rather than letting a TeX Live installation bring it in, that naming is a reminder to record the tag you actually used, because the version string alone will not tell you much.
The develop branch is the default, but the build badge watches main
GitHub reports the default branch as develop, which fits a project whose stable output is curated elsewhere. The README's build status badge, however, is a GitHub Actions workflow URL carrying a branch query of main. Those two statements do not agree.
It is a small inconsistency and it is the kind of small inconsistency worth naming rather than smoothing over. A badge pointing at a branch that is not the default branch may reflect a workflow that still runs on main, a badge that was not updated when the default branch changed, or a repository that keeps both branches active for different purposes. The tree offers no way to tell which, since the repository fields here expose only the default branch name.
What is not in doubt is the shape of the thing. LaTeX3 was supposed to be a language rewrite, expl3 is the implementation that survived by being absorbed into LaTeX2e, and this repository is where that absorption is worked on. The directory names are the most useful documentation in it: read them before you import anything, because they tell you whether a module is stable, experimental, or explicitly unreleased.
Editorial conclusion
This repository is a working laboratory rather than a package you add to a document, and the directory names are the honest signal about what is safe to use. Code in l3kernel is what a modern LaTeX2e loads for you, l3packages is history, l3experimental is for interfaces still under discussion, and l3trial never reaches CTAN at all. Start by reading the l3kernel header comments in the LaTeX distribution you already have, and treat anything you find in l3experimental as something that can move underneath you without a deprecation cycle.
Frequently asked questions
What is the difference between latex3 and LaTeX2e?
LaTeX2e is the current LaTeX kernel. LaTeX3, whose implementation is called expl3, was designed as the language that would follow it. Rather than replacing LaTeX2e, expl3 was absorbed into it, which is why the README explains loading in terms of kernel versions instead of package versions.
Is expl3 code safe to use in a published document?
It depends entirely on which directory it comes from. Code in l3kernel is described as stable and is loaded automatically by a modern LaTeX2e kernel. Code in l3experimental is for interfaces still under active discussion, and code in l3trial is never released to CTAN at all, so it can change or vanish without any deprecation cycle.
Why does l3packages look abandoned?
The README says so directly: l3packages is now made up of historical material and its concepts have been migrated to the LaTeX2e kernel. If you are looking for an expl3 macro you remember from a tutorial, it may have moved out of this repository entirely.
How are expl3 releases named?
By date rather than version number. Recent tags include 2026-09-09, 2026-09-09-dev and 2026-08-10. There is no semantic version string and no changelog attached, so compatibility with a particular LaTeX2e kernel has to be established from the tag you pinned rather than from the name.
Does this repository contain the LaTeX3 documentation?
Not the user documentation. The articles and discussionpapers directories hold conceptual writing by team members intended for TUGboat and similar venues, which is design rationale rather than a manual. Usage documentation ships with the LaTeX distribution itself, in the expl3 code loaded by the kernel.
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/latex3-latex3)