So I got into the whole idea of learning plain TeX (or what I think is plain TeX) and it's been very fun and rewarding. I also started writing some macros/packages for my personal use for now. Since for the main document I (still) use LaTeX as well as lots of high level packages, it really doesn't matter if the packages I write are written in plain TeX, plain LaTeX or use xparse, etoolbox, etc... But I'm wondering:

  1. What is good practice for package writing? Especially if I want to distribute that package one day. On the one hand, plain TeX is more powerful, much more portable and static (the output will not change in time or across different compilers). On the other hand, it's more prone to mistakes due to the programmer (me) not fully understanding all the subtleties in the general usage case. One example would be the robustness of commands, but I'm sure more experienced folks can give many more examples of rookie traps.

  2. If I do use LaTeX in the package, what are the advantages and disadvantages of relying on extra packages such as xparse or etoolbox

  3. Also, how can I know for sure (without digging through the files that came with my distribution) if a plain old command is a TeX primitive or a LaTeX kernel command - is the case that ALL LaTeX kernel commands have at least one @ and no TeX primitives have that? Is it ok if inside the package I mix TeX with some of those LaTeX kernel commands? (I'd assume they're pretty stable and don't change much across versions?)

  • 2
    This is close to a duplicate of tex.stackexchange.com/questions/7278/reasons-to-use-plain-tex/…. This question has a very through set of good answers. Commented Jan 31, 2016 at 2:39
  • As I understand - which is not at all well - xparse is intended to provide a user interface. That is, you use the macro creation commands there to provide the user interface you want users to have in a document which uses your class or package. These are then supposed to just select which internal macros to use and the internal macros (in expl3 syntax, presumably) should do the real work. However, templates are supposed to fit in here somewhere as well, and my current understanding doesn't seem to have room for them.
    – cfr
    Commented Jan 31, 2016 at 2:56
  • 1
    @R. Schumacher Thanks, I did read quite thoroughly through that question beforehand, but since it was more about personal choice I thought I'd make my question more specific to packages, which I intend to distribute in the future. Most packages I've seen on CTAN are written in plain Tex, but I've seen quite a few which assume the user uses a new-ish LaTeX distro and take advantage of xparse for example. I was just wondering if this is frowned upon, what would e.g. ConTeXt users do. Commented Jan 31, 2016 at 2:58
  • @cfr yes, xparse does simply provide a more robust and flexible interface to LaTeX's macro defining... macros. But still it requires LaTeX, correct? Commented Jan 31, 2016 at 3:00
  • 4
    Nice question, and I agree not at all a duplicate of the linked one. I suspect there is no perfect answer, and answers might well depend a lot on one's own TeX skills. But some higher level packages like etoolbox are widely used and of course some people are now writing packages directly using expl3.
    – Alan Munn
    Commented Jan 31, 2016 at 4:06

3 Answers 3


Technically using plain tex is not an option, plain is the format produced by inputting the file plain.tex into initex and that file is not used in LaTeX at all.

It is however true that many of the commands that are defined in plain TeX have commands of the same name defined in LaTeX, and in some of those cases, the definitions are the same.

The commands in the LaTeX format and the standard classes are written in a mixture of "low level" macros and TeX primitives that are more or less analogous to plain tex. At the time they were written (1985-1993) doing anything else would not have been an option, early versions of what is now called xparse were already available at that time but there was not enough memory left to process any real documents, and even test documents took "a while..."

Now it depends. It is of course always more efficient in machine time to use a lower level interface but may be less efficient in human time in development and maintenance. This applies to any computing language not just TeX. For most people most of the time it is better to write code in a high level system, but for some people for some core code it is still effective to write code in processor-specific machine code assembler as a human expert can still do better than a compiler.

If you use low level commands then it might be more efficient but you might break something. There was a question here recently when someone had gone \def\box{....} and then wondered why things didn't work. Similarly if your document is also using higher level packages such as expl3 or pgf then if you update the structures those packages need via the documented package interfaces then the structures are far more likely to be internally consistent than if you just poke in some new values with \let or \def.

On the other hand if, as often happens, your definition is a variation or extension on an existing definition then it makes sense to code it in the same style, for ease of code re-use but also for documentation reasons to make it more easy to see the differences. So it is not possible to give blanket advice that for latex2e all packages should be written in expl3 or whatever.

One other consideration that pushes towards low level code is that you may want the package to work with plain tex (and possibly context or eplain or lollipop or ...) without having to load a definitional layer such as expl3-generic or miniltx.tex. The ltluatex code for low level luatex support is for example written to work unchanged with plain TeX even though it is distributed as part of the LaTeX base.

So if starting a completely new code and you want to provide a natural interface and documentable structure to the code I would use expl3. If you are adapting or modifying existing code or have other real world constraints then it's complicated and the end result is usually a compromise.

The LaTeX kernel itself is very stable and (apart from some changes to address new engines such as luatex) has not really changed since LaTeX2e stabilised in the the 1990's. Since the 2015 release some bug fixes have been added but they are all guarded by conditional code in the source file which allows the latexrelease package to wind back the definitions to an earlier release if necessary.

  • 4
    Excellent answer: perhaps note that expl3-generic is loadable on plain/LaTeX/ConTeXt/.... You might also note that LaTeX2.09 did load plain (or rather was a .tex file to be \input like any other).
    – Joseph Wright
    Commented Jan 31, 2016 at 10:24
  • @JosephWright I meant to imply expl3 could be used that way like miniltx, I'll use expl3-generic to make that clearer. Even 2.09 used lplain rather than plain (although there were fewer differences in that case) Commented Jan 31, 2016 at 10:30
  • Th 'historical latex.tex on CTAN is loadable with plain ...
    – Joseph Wright
    Commented Jan 31, 2016 at 10:51
  • @JosephWright you can load latex.ltx on plain as well tex.stackexchange.com/questions/91042/… Commented Jan 31, 2016 at 11:05
  • 1
    It seems worth pointing out that the analogy you are making where TeX is to LaTeX as Assembly is to (say) C, is limited. You say sometimes it is better to write in assembly since a human can optimize better than a compiler. But that is because there is no exact correspondence between "high-level" C code and the assembly language produced by a compiler (of course, that's the whole point of C, to be portable). But in LaTeX, we know exactly what TeX primitives the commands will be expanded to. \newcommand is not equivalent to \def; it calls \def but also does other things. (right?) Commented Feb 1, 2016 at 4:06

So I got into the whole idea of learning plain TeX

OK, welcome:)

1. What is good practice for package writing?

Typically, plain TeX users don't use packages from third side. They started with fixed point which is plain.tex file and do own macros. But there is a problem about "reinventing wheel". For example they must do own macros for table of contents, colours, references, bibliography etc. So, I did a macro OPmac and released it as public available. The main principle is simplicity, see the summary. And second principle is:

Do not try to make new language level with plenty of keywords, identifiers and new syntax. Give simple default macros only and say: "if you need something different, redefine them." This is typical plain TeX approach. The most powerful language is ready to use: the TeX macro language.

If you use only TeX primitives and basic plain TeX macros (like \newcont allocator) in your packages then your code will be applicable everywhere: in plain TeX, LaTeX and ConTeXt, for example. Unfortunately, this "good practice" is not observed in LaTeX packages. For example the qrcode.sty is usable macro for QR codes printing results by \hrule, \vrule primitives. But this macro is mix of TeX primitives (like \def, \advance) basic plain TeX macros (like \newcount) and LaTeX macros (like \newcommand, \addtocounter, \newcounter). IMHO, this is very bad practice. The qrcode.sty is not applicable in plain TeX or ConTeXt, for example. So I removed the LaTeX specialities from qrcode.sty and released qrcode.tex here.

2. If I do use LaTeX in the package, what are the advantages and disadvantages...

Sorry, I don't see any advantages. The result is LaTeX specific, LaTeX dependent and this is not good idea. The TeX macro language is sufficiently powerful.

3. Also, how can I know for sure (without digging through the files that came with my distribution) if a plain old command is a TeX primitive

For example, what you see in the Index of TeXbook. Or in my book TeXbook naruby, the appendix B lists all TeX primitives and macros of plain.tex including explanation. The marks (used here) e, h, v, m mean that the control sequence is expandable, horizontal, vertical or math-mode primitive. And [plain] means plain TeX macro.

You cannot distinguish LaTeX macros from plain TeX macros by presence of @ character, because plain TeX includes control sequences with @ too. Unfortuately, this was not a good idea for name spaces. Namely, TeX is unable to deal with name spaces and the rules to put something to each new allocated control sequence is only agonised experiment to solve this. But plain TeX user knows the TeX primitives and he/she is able to allocate new names with respect to this "only one name space".

  • 4
    Thus is really an answer to the linked question It doesn't really address this question at all which is specifically about latex package writing. Clearly the vast majority of latex packages will use commands using latex syntax, not least for option handling. The question is about the extent to which one should use plain tex compatible commands in addition. Commented Jan 31, 2016 at 12:31
  • 1
    @David Carlisle Actually, my question was about general package writing since I'd like to distribute those packages (in the far future) for other people to use and maybe switch away from LaTeX myself, should I decide to one day. Maybe I didn't state my question very clearly. Thanks to both for your extensive answers though! Commented Jan 31, 2016 at 13:02
  1. Try to use as less package dependent macros as possible, and organize your general purpose ones in a small file. You may have a look at Paul Isambert's TeXapi and YaX packages, which may provide you with an interface to write format independent macros; they are used by his lecturer and navigator packages, which can run on Plain, LaTeX and ConTeXt.

  2. Skip.

  3. Grab a copy of TeX for the Impatient and keep it near your desk.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .