You hit submit on a paper and the portal rejects it: 8,214 words against an 8,000 limit. In a word processor you would have seen that coming. LaTeX hides the number, because your .tex file is full of markup that isn’t text. This guide is the practical end of LaTeX word counting: the commands you actually run, how to wire them into your editor and build, and how to match the count a journal or thesis office expects. It also compares the counting methods directly, so you can see why detex, a script, and texcount disagree.
The short version: install texcount, run it, configure a couple of comment directives for your custom macros. Most people never need more.
Why the number is hard to get
A .tex file mixes three things that all look like text to a naive counter. Real prose. Markup such as \section{}, \cite{}, and \ref{}. And math, where $\alpha + \beta$ is two symbols, not two words. Add captions, footnotes, comments, and multi-file projects with \input, and “how many words is this” stops having one answer.
That ambiguity is the whole game. A journal that says “6,000 words excluding references and captions” is describing a counting rule, and your job is to reproduce it. So before counting, find out what the count is supposed to include.
texcount: install it once
texcount is a Perl script that ships with TeX Live and MiKTeX, so if you have a LaTeX install you very likely already have it.
# Check whether it's already there
texcount --version If it isn’t on your PATH:
# Debian/Ubuntu (TeX Live)
sudo apt-get install texlive-extra-utils
# macOS with MacTeX/Homebrew
brew install texcount On Windows with MiKTeX or TeX Live it’s installed alongside the distribution. If texcount isn’t found, the binary lives in the distribution’s scripts directory; add that to PATH.
The commands you’ll actually use
Start plain:
texcount thesis.tex You get a breakdown: words in text, words in headers, words in captions, plus counts of headers, floats, and inline and display math. That separation is the point. A “6,000 words” limit almost always means words in text, not the grand total.
A few flags cover most real needs:
# One-line summary, good for scripts
texcount -brief thesis.tex
# Follow input and include across the whole project
texcount -inc main.tex
# Per-chapter / per-section subcounts
texcount -sub thesis.tex
# Verbose: prints the document with words marked, so you can see
# exactly what it did and didn't count
texcount -v thesis.tex The -v mode is underrated. When a count looks wrong, run it and read the colour-coded output. You’ll usually spot the culprit immediately, a custom macro swallowing a paragraph, or a caption counted when you wanted it excluded.
Excluding and including the right parts
The decisions a word limit cares about are usually captions, headers, and the bibliography.
# Drop headers and captions from the total
texcount -nosub -sum thesis.tex # -sum reports a single combined number...
texcount -merge -sum main.tex # ...and -merge folds input files into one count
# Include the bibliography in the count
texcount -incbib paper.tex By default texcount counts citation keys, not the rendered bibliography, which is what most limits want. Use -incbib only when a limit explicitly counts the reference list.
Custom macros and environments
Real documents define their own commands, and texcount can’t guess what they do. You teach it with %TC: directives placed as comments in your source. They live in the .tex file, so the rule travels with the document.
% Treat the argument of \keyword as countable text
%TC:macro \keyword [text]
% Ignore a custom \todo note entirely
%TC:macro \todo [ignore]
% Don't count the contents of a solution environment
%TC:envir solution [ignore] ignore The %TC:envir line takes the environment name, how to handle its arguments, and how to handle its body. ignore for both drops it completely. If your numbers look off by a chunk, an uncounted custom environment is the usual reason.
Math
By default texcount reports inline and display math as separate tallies rather than folding them into the word total, which is the honest default. If a particular journal wants display equations counted as words, you can change that per environment with the same directive syntax.
Matching a specific requirement
Journals
Read the author guidelines, then translate them into flags. A limit that excludes references and captions maps to something like:
texcount -merge -sum -nosub paper.tex When you report the number, note the method. Editors rarely argue with “6,142 words (texcount, main text, excluding references and captions).”
Theses
University regulations vary, and many count the main body only, excluding front matter, bibliography, and appendices. Split the project so the rule is easy to apply:
# Main chapters, combined
texcount -merge -sum chapter*.tex
# Appendices reported separately
texcount -merge -sum appendix*.tex If your regulations give a character limit instead of words, texcount -char and -charws (with whitespace) cover both readings.
Wiring it into your workflow
Editor integration
In VS Code with the LaTeX Workshop extension, texcount drives the status-bar count:
{
"latex-workshop.wordcount.path": "texcount",
"latex-workshop.wordcount.args": ["-inc", "-merge", "%DOC%"]
} TeXstudio and TeXmaker have built-in word-count entries that call texcount under the hood, so the same logic applies without configuration.
Build and CI
For a hard limit, fail the build when you exceed it. The -1 flag prints just the number, which is what you want in a script:
#!/bin/bash
LIMIT=8000
COUNT=$(texcount -1 -sum -merge main.tex)
if [ "$COUNT" -gt "$LIMIT" ]; then
echo "Word count $COUNT exceeds limit of $LIMIT"
exit 1
fi Drop that into a Git pre-commit hook or a CI step and you’ll never be surprised by the submission portal again.
The other counting methods, and when they win
texcount is the default for good reason, but it is not the only way to count, and knowing what the alternatives actually measure tells you when a number is trustworthy.
The trouble underneath all of this is that a .tex file is source code, not finished text. The same file holds prose, markup such as \section{} and \cite{key}, math where $x^2 + y^2 = z^2$ renders as symbols rather than five English words, comments after % that never reach the reader, and captions and footnotes that a limit may or may not include. Every counting method is really a set of decisions about those categories.
wc on the raw source
wc -w document.tex This is wrong on purpose. It treats \section{Introduction} as words and counts every command, so the result is inflated and meaningless for a submission. It is still useful as a sanity check: if texcount says 6,000 and wc says 6,400, the gap is roughly your markup, which is plausible. A gap of 3x means something is misconfigured.
Strip the markup, then count
Remove LaTeX commands first, then run a plain word counter. The classic tool is detex, which ships with most TeX distributions.
# Strip LaTeX, then count
detex document.tex | wc -w
# -l forces it to follow input and include
detex -l main.tex | wc -w Stripping is fast and dependency-light. Its weakness is that it does not understand context. detex keeps the readable text of some commands and drops the argument of others, so captions and footnotes get treated inconsistently, and math handling is hit or miss. For a rough running total this is fine. For a hard limit it is too approximate.
A script you control
When you need counting rules no tool offers, a small script gives you full control.
import re
import sys
def count_latex_words(path):
with open(path, encoding="utf-8") as f:
content = f.read()
# Drop comments (a % not preceded by a backslash)
content = re.sub(r"(?<!\)%.*", "", content)
# Drop inline and display math
content = re.sub(r"$$.*?$$", "", content, flags=re.DOTALL)
content = re.sub(r"$[^$]*$", "", content)
# Remove commands along with their first {...} argument
content = re.sub(r"\[a-zA-Z]+*?([[^]]*])?({[^}]*})?", "", content)
return len(re.findall(r"w+", content))
if __name__ == "__main__":
print(count_latex_words(sys.argv[1])) Be honest about what this is: a heuristic. Regex cannot truly parse LaTeX, so nested braces, verbatim blocks, and unusual environments slip past it. The value of rolling your own is not accuracy, it is that you can encode a rule your institution invented, like counting everything in \chapter bodies but nothing in \marginpar.
Picking between them
| Method | Accuracy | Setup | Best for |
|---|---|---|---|
wc -w | Poor (counts markup) | None | A quick sanity check |
detex + wc | Rough | Usually preinstalled | Running totals while drafting |
| texcount | High | Install once, add directives | Submissions, theses, the default choice |
| Custom script | As good as you make it | Real work | One-off institutional rules |
For the overwhelming majority of cases the answer is texcount. The others earn their place either as a cross-check or as an escape hatch when no tool matches a strange requirement.
Counting without installing anything
If you’re writing in the browser, the count is just there. An online editor parses the document as you type and keeps a running figure, the same way a word processor does. inscrive.io shows a live count and recomputes across a multi-file project on every compile, so the number reflects what \input actually pulls in. Because editing is real-time and collaborative, the figure stays current while several authors work on the same file.
inscrive is freemium: the Free plan (€0, up to 10 active projects, 60-second compiles) is enough for most single papers, and Pro (€7/month) lifts compile time to 480 seconds and adds AI-suggested fixes for compile errors. Documents are stored entirely in the EU (Hetzner data centres in Germany and Finland, ISO 27001 certified), and your work is never used to train AI models. New to the browser workflow? The beginner’s guide to LaTeX is a good starting point, and the online editor comparison covers how the options differ.
A workable default
There is no single correct LaTeX word count, only a count that matches the rule you were given. Whatever you choose, record the method next to the number. A count without its method is just a guess that happens to have digits.
For most documents this is enough:
texcount -inc -sum -brief main.tex Add %TC: directives for any custom macro that’s throwing the count off, decide once whether the bibliography is in or out, and write the method down next to your draft. That last habit, recording how you counted, saves more arguments with editors than any flag.
Want the count without the setup? Start writing on inscrive.io for free and watch the word count update as you type, across every file in the project.
Further reading
- texcount manual, the official documentation
- LaTeX beginner’s guide, if you are new to the markup
- Online LaTeX editors compared, for how browser editors differ




