• A lot of people learn LaTeX in TeXworks. It ships with TeX Live and MiKTeX on Windows, it’s what many courses hand you on day one, and it does exactly what a first editor should: a source window, a PDF window, and a green button that turns one into the other.

    Then you move to a Mac, or your document grows past a single file, and you start looking for what comes next. This is an honest map of the options.

    First: you can keep using TeXworks

    TeXworks runs on macOS. There are official builds on the project’s GitHub releases page, and it’s available through Homebrew:

    brew install --cask texworks

    It doesn’t bundle a TeX distribution, so you’ll want MacTeX (or the smaller BasicTeX) installed first. If which xelatex prints a path in Terminal, you’re set.

    If TeXworks is working for you, there’s no reason to leave. But if you’re searching for alternatives, something has probably started to pinch.

    Where TeXworks starts to pinch

    TeXworks was designed to be simple, and its limits are mostly the flip side of that choice.

    • Multi-file projects. Once a thesis is split into main.tex and a folder of chapters, the structure sidebar only shows the file you’re looking at. There’s no view of the whole document.
    • Autocompletion. Completion comes from fixed word lists, not from your project. Typing \ref{ won’t offer the labels you defined in chapter three, and \cite{ won’t offer your .bib keys.
    • Finding errors. When a build fails, you read the console output and work out which file and line TeX was complaining about.
    • Feeling at home on a Mac. TeXworks is a cross-platform Qt application. It works, but it doesn’t always behave like the rest of macOS.

    None of these matter for a ten-page paper. All of them matter by chapter six.

    The alternatives

    TeXShop — the one already on your Mac

    If you installed MacTeX, you already have TeXShop in /Applications/TeX. TeXworks was modeled on it, so the two-window workflow will feel familiar, and it’s a native Mac app. It’s free and mature. It’s the closest thing to “TeXworks, but on a Mac” — which also means it shares a similar philosophy of keeping things minimal.

    TeXstudio — everything, everywhere

    Free, open source, and packed with features: a structure view that follows included files, completion for labels and citations, an error list, a long menu of tools. If you want maximum capability without paying, this is the usual answer. Like TeXworks, it’s a cross-platform Qt app, so on a Mac it trades some polish for breadth.

    VS Code with LaTeX Workshop — if you already live in VS Code

    A general-purpose editor turned into a capable LaTeX environment by one extension. Strong on configuration, multi-file support, and everything else the VS Code ecosystem brings. The cost is setup: it’s a toolkit you assemble rather than an editor that arrives ready.

    Overleaf — if you’d rather not install anything

    LaTeX in the browser, with real-time collaboration that nothing local can match. Your documents live on Overleaf’s servers, and some features — longer compile times, full history, more collaborators — sit behind a subscription.

    texspark — native, and built for multi-file projects

    Full disclosure: we make this one. texspark is a native macOS editor built specifically around the point where TeXworks starts to pinch — a project that outgrew one file. The outline covers the whole \include tree, \ref{ and \cite{ complete from across the project, and ⌘-clicking the PDF opens the sub-file the text came from. It’s paid, with a 14-day free trial and no signup.

    Moving your project over

    The good news: there’s nothing to convert. Your files are plain .tex, and every editor above reads them as-is. A few habits are worth checking, though.

    Magic comments. TeXworks users often put these at the top of each chapter file:

    % !TEX root = ../main.tex
    % !TEX program = xelatex

    The first tells the editor which file to compile when you’re editing a chapter; the second picks the engine. TeXShop, TeXstudio, and LaTeX Workshop all understand a version of these, so they’ll mostly carry over. Overleaf sets the main document and compiler in the project menu instead. texspark uses a build target: double-click the root file’s tab once, and ⌘B compiles it from any chapter. The engine lives in the project’s build command.

    SyncTeX. TeXworks passes -synctex=1 in its default tool configurations, which is why clicking between source and PDF just worked. If you set up a custom build command elsewhere, make sure the flag comes along — otherwise jumping between source and PDF will quietly stop working.

    Your TeX distribution stays. None of these editors replace MacTeX; they all drive the same xelatex or pdflatex underneath. Switching editors doesn’t change your output.

    Picking one

    • You liked TeXworks’ simplicity and just want it to feel at home on a Mac → TeXShop
    • You want every feature, free → TeXstudio
    • You already write code in VS Code → LaTeX Workshop
    • You collaborate, or don’t want to install anything → Overleaf
    • Your project is many files and you want a native Mac app built for that → texspark

  • They look like the same environment with a suffix, and the documentation tends to describe them in terms of “inner” and “outer” mode, which doesn’t help much when you just want your equations to line up. Here’s the short version:

    gather stands on its own and numbers every line. gathered lives inside something else and has no numbers of its own. That single difference explains everything else.

    Both need amsmath.

    gather — several equations, several numbers

    Use it where you’d use equation, in the flow of your text. Each line gets centered and numbered separately:

    \begin{gather}
      E = mc^2 \\
      F = ma
    \end{gather}

    That produces two equations with two numbers. You can suppress one with \notag, label them individually, and use gather* if you want none of them numbered.

    What you cannot do is put it inside another math environment. gather expects to be at the top level, and nesting it will get you a math delimiter error.

    gathered — one block, one number

    gathered is a building block. It has to sit inside a math environment, and it borrows that environment’s numbering:

    \begin{equation}
      \begin{gathered}
        E = mc^2 \\
        F = ma
      \end{gathered}
    \end{equation}

    Same two lines, but now one number for the pair, placed beside the block as a whole. That’s usually the reason people reach for it: two or three lines that belong together conceptually and shouldn’t be numbered separately.

    Used on its own, outside math mode, it will fail — typically with a missing-$ complaint, since TeX hits math content where it expected text.

    The thing only gathered can do

    Because it’s a box rather than a full-width display, gathered takes an optional vertical alignment argument — [t], [c], or [b] — and can be placed next to other material.

    \[
      \left\{
      \begin{gathered}[t]
        x + y = 1 \\
        x - y = 3
      \end{gathered}
      \right.
    \]

    Two gathered blocks can also sit side by side in one display, aligned at their tops or bottoms. gather can do none of this — it always occupies the full width.

    You might want gather* instead

    A common detour: someone wants a few unnumbered equations stacked up, reaches for gathered, and then has to wrap it in \[ ... \] to make it work. That detour exists because gather* was the answer all along.

    Reach for gathered when you need the block to share a number with its parent, or when it has to sit inside something else. If you just want no numbers, the starred form is simpler.

    The same pattern, everywhere

    Once you see it, amsmath gets much easier to remember. The -ed suffix always means “the inner version of this”:

    • gather / gathered — centered lines
    • align / aligned — lines aligned at &
    • alignat / alignedat — same, with manual column spacing

    And split is the special case: an inner environment like aligned, but designed specifically to break a single equation across lines under one number.

    Deciding in one step

    Ask how many equation numbers you want.

    • One per line → gather
    • None → gather*
    • One for the whole block → equation + gathered
    • It needs to fit inside a brace, a cell, or beside something else → gathered

  • You ⌘-click a line in the PDF and the editor lands three pages away. Or nothing happens at all. SyncTeX is one of those features that either works invisibly or fails confusingly, with not much in between.

    Here’s what it’s actually doing, and the four reasons it goes wrong.

    What SyncTeX is

    When TeX typesets your document, it normally throws away the connection between source and output. A line of .tex becomes ink on a page and the relationship is forgotten.

    SyncTeX keeps a record of it. Compile with the flag on and you get a .synctex.gz file next to your PDF — a compressed map from source positions to page coordinates, and back. Your editor reads that map to answer two questions: “the cursor is on line 412, where is that in the PDF?” (forward search) and “the user clicked here on page 87, where did it come from?” (inverse search).

    Everything that goes wrong is a problem with that map — it’s missing, it’s stale, or it points somewhere your editor can’t follow.

    Nothing happens at all

    The map doesn’t exist. Check the folder your PDF is in — if there’s no .synctex.gz (or an uncompressed .synctex), the flag isn’t on. Add it to your compile command:

    xelatex -synctex=1 main.tex

    With latexmk, add it to the engine options rather than latexmk itself:

    latexmk -pdf -pdflatex="pdflatex -synctex=1 -interaction=nonstopmode" main.tex

    One thing that catches people: some build scripts clean aux files afterwards and sweep the .synctex.gz away with them. If the file appears during the build and vanishes when it finishes, that’s your culprit.

    It jumps, but to the wrong line

    The map is stale. It describes the document as it was at the last compile, and you’ve edited since. Add twenty lines near the top and every position below shifts by twenty — SyncTeX has no idea.

    Rebuild and the offset disappears. If it persists after a clean rebuild, the map is genuinely confused rather than out of date, which usually means one of the cases below.

    It lands in the wrong file

    This is the multi-file case, and it’s where editors differ most.

    SyncTeX itself handles it fine. The map records which file each piece of text came from, so a paragraph pulled in through \include{chapters/ch7} is tagged as belonging to ch7.tex, not to main.tex. The information is there.

    What varies is whether your editor acts on it. Some read only the file they compiled and land you at the corresponding line of main.tex — which is meaningless, since main.tex is forty lines of preamble and a list of includes. Others open the right file but lose the build target, so your next ⌘B tries to compile a chapter with no \documentclass.

    If your jumps consistently land in the root file, that’s not SyncTeX failing. That’s the editor ignoring what the map already knows.

    The paths are wrong

    Rarer, but worth knowing. The map stores file paths as TeX saw them at compile time, relative to the working directory. If you compile from one directory and open the PDF from another — a build script that cds somewhere, an output directory set with -output-directory, a project moved after building — the paths no longer resolve.

    Symptom: jumps work for the root file but silently fail for anything included. Fix: compile from the directory your source lives in, or rebuild in place after moving things.

    How texspark handles it

    The default build commands in texspark include -synctex=1, so the map is there without you thinking about it, and builds run in the build target’s own directory — which keeps the recorded paths resolvable.

    For the multi-file case: ⌘-clicking the PDF opens the sub-file the text actually came from, at the right line, however many \include levels deep it sits. The build target stays on your project root, so ⌘B from that sub-file still compiles the whole document. Forward search (⌘⇧↩) works the same way in reverse, from any chapter.

    If something here doesn’t match what you’re seeing, email support@texspark.io — it goes straight to the developer.


  • You ran a build, it failed, and while scrolling the log you found this near the top:

    restricted \write18 enabled.

    It is an informational LaTeX message, not an error. It means restricted shell escape is active: TeX can run certain permitted external commands.

    If your build failed, look further down the log for the first error message—often a line beginning with !. Start with that error and its surrounding lines, rather than changing shell-escape settings just because you saw this status message.

    What the line actually means

    \write18 is TeX’s mechanism for running shell commands during compilation — historically, stream 18 was the one wired to the operating system. A package can use it to call external programs mid-build: syntax highlighters, plotting tools, image converters.

    Running arbitrary shell commands from a document you may have downloaded from the internet is, obviously, a security hazard. So modern TeX distributions ship with a compromise: restricted mode. A short, vetted whitelist of safe programs (like bibtex, kpsewhich, epstopdf) is allowed to run; everything else is blocked. The log line is simply the engine announcing this default state:

    • restricted \write18 enabled — the normal, safe default. Whitelisted helpers can run, nothing else.
    • \write18 enabled (no “restricted”) — full shell access is on, because you passed -shell-escape.
    • \write18 disabled — shell access is fully off, usually via -no-shell-escape.

    It’s an informational status line, printed before your document is even read. It cannot be the reason your build failed.

    So where is the real error?

    Further down. In a TeX log, actual errors start with ! at the beginning of a line — for example:

    ! Undefined control sequence.
    l.42 \includegraphcis
                          {fig/tree.pdf}

    Search the log for a line starting with ! (in a text editor, search for a newline followed by !), and read the l.<number> line below it — that’s the file line where TeX gave up. If there’s no ! at all, check for Emergency stop or a missing-file message like LaTeX Error: File '...' not found.

    When you actually need \write18

    Some packages genuinely need to run external programs, and restricted mode is not enough for them. The usual suspects:

    • minted — calls Pygments for syntax-highlighted code listings
    • gnuplottex / pgfplots with external data pipelines — call gnuplot
    • svg — calls Inkscape to convert SVG figures
    • tikz externalization — compiles each TikZ picture as a separate job to speed up rebuilds

    These packages fail with messages like Package minted Error: You must invoke LaTeX with the -shell-escape flag — which is your cue, and the only situation where changing the default makes sense. Add the flag to your compile command:

    xelatex -shell-escape -synctex=1 main.tex

    One honest caution: -shell-escape means the document can run any command your user can. That’s fine for your own manuscript; it’s worth a moment’s thought before compiling a .tex file a stranger sent you. Turn it on for projects that need it, not globally.

    Setting it per project in texspark

    In texspark, the build command is an editable shell command, remembered per project — so -shell-escape lives only where it belongs. Edit the command in the Terminal panel’s header (or Preferences → Compile) for the project that needs it:

    xelatex -interaction=nonstopmode -synctex=1 -shell-escape {file}

    Your other projects keep the safe default. And when a build does fail, the Issues panel has already parsed the log for you — every ! error listed with its file and line, one click from the offending spot. No scrolling past status lines that were never the problem.


  • The last few weeks have been a small education in rejection.

    I sent the manuscript to publishers. The replies came back — polite, professional, no. Then again. Then again.

    My first instinct was to look inward, which felt like the responsible thing to do. If they’re saying no, something must be wrong with the book. So I revised. I tightened chapters, rewrote a derivation I’d never been happy with, went through the figures again. Each pass made the manuscript a little better.

    But somewhere around the third round, I had to admit something: no amount of polishing was going to reverse those decisions. The gap between “good draft” and “yes” wasn’t a gap of quality. It was something else.

    The something else

    Publishing draws a line between two kinds of books: the trade book — something a curious reader picks up in a bookstore — and the textbook, which lives in classrooms and has adoption cycles and a syllabus around it.

    I’d been pitching mine as a trade book. Twelve chapters of derivations, exercises, from-scratch implementations. A book that assumes you’ll work through it rather than read it on a train.

    That’s not a trade book. That was never a trade book. I’d been walking into the wrong department and wondering why nobody wanted what I had.

    It’s a strange kind of relief, discovering that the problem is a category error. The manuscript wasn’t failing. It was in the wrong queue.

    Putting it down

    So I repositioned it as a textbook, made the revisions that framing called for, and then — the harder part — stopped.

    There’s always one more pass available. Another derivation to smooth, another figure to redo. At some point continuing to revise stops being craftsmanship and starts being avoidance, and I think I got close enough to that line to see it. The draft is good. Not perfect; good. I put it down.

    It’s now with publishers who actually work in textbooks, and I’m back to waiting — but this time waiting on the right people.

    What I’ve been doing instead

    Not writing, mostly. Which turns out to be its own kind of progress.

    I’ve started a new research topic — the first genuinely new thing in a while — and drafted a paper around it. And in the way these things go, working on that paper sent me back into texspark’s source: new usage patterns, new small frictions, new fixes. The tool improves when I use it for something I haven’t used it for before.

    The book is where it is. Somebody will read it eventually, or they won’t, and either way it exists now, which was never guaranteed. Meanwhile there’s a paper to write, and an editor to improve, and — as always — one more thing to fix before I can get back to writing.


  • My referrer list is short enough that I read it like a diary. Google, Twitter, a few direct visits. Last week a new entry appeared: chatgpt.com. One visitor.

    Somebody asked ChatGPT something — probably about LaTeX editors on macOS — and ChatGPT mentioned texspark, and that person clicked. I have no idea who they were or what they asked. But I know how they got here, and the path is worth writing down.

    The chain, visible in my logs

    Because this site is small, I can see the whole sequence rather than infer it. Three entries, weeks apart:

    • Early July — OAI-SearchBot shows up in my download log. OpenAI’s search crawler, indexing the site.
    • Mid July — GPTBot follows. The one that reads pages so ChatGPT can talk about them.
    • Early August — a human arrives with chatgpt.com as their referrer.

    Crawl, index, recommend, click. The same loop search engines have run for twenty-five years, except the last step now happens inside a conversation instead of on a results page.

    Why this is stranger than it sounds

    Here’s the part that made me stop: texspark ranks terribly on Google. Average position across all my search terms is somewhere around 35 — page four, where nobody goes. I’ve been patiently waiting months for that number to improve, because that’s how this is supposed to work: you write, you rank, eventually you get clicks.

    But ChatGPT doesn’t rank pages. It reads them and decides which one actually answers the question. Domain authority, backlink count, how old your domain is — the machinery that keeps a new site buried on page four — matters much less. What seems to matter is whether your pages state clearly and specifically what your thing is and isn’t.

    Which means the pages I wrote for humans — the honest comparisons, the “here’s what Texmaker does better” sections, the documentation with actual keyboard shortcuts in it — may be doing their most useful work in a channel I wasn’t even aiming at.

    One visitor is not a trend

    Let me be clear about the sample size: it’s one. One person, one click, no evidence they downloaded anything. I’m not about to reorganize my writing around “LLM optimization,” which sounds like a phrase that will age badly and probably already has a conference track.

    But it does suggest something worth noticing. For a small, new site with no backlinks and no authority, AI search may be a faster path to being found than climbing Google’s rankings. Not because you gamed anything — just because a model reading your page has no reason to care that your domain is four months old.

    The advice, if there is any, is unglamorous: write pages that are specific and true. Say what your software does, what it doesn’t, and who it isn’t for. That’s been good advice for humans forever. It now appears to also be good advice for the machines quoting you to humans.

    Anyway — hello, whoever you were. You’re in a chart now.


  • Today I sent the full manuscript of Machine Learning from Scratch — all twelve chapters — to an editor, along with the proposal. First complete draft, out the door.

    It’s a strange feeling. For months the book was entirely mine: my pace, my decisions, my endlessly rearranged outline. I could open any chapter at 2 a.m. and change a derivation on a whim. Now a complete draft sits in someone else’s inbox, and for the first time the next move isn’t mine to make.

    The writing happened faster than I expected once the editor I was building — texspark — got out of my way. Twelve chapters of equations, figures, and derivations, typeset in LaTeX, written in an app that grew up alongside the manuscript. At some point the tool stopped being the project and became just the thing I wrote in, which was always the goal.

    There’s a lot still ahead: an editor’s read, revisions, the whole publishing pipeline that turns a folder of .tex files into something with a spine. But a first complete draft is a real threshold, and it’s crossed.

    For now, the book is out of my hands. Back to refreshing my email.


  • When you tell people you’re writing a machine learning book, they assume a stack: Jupyter notebooks, Markdown, maybe a static-site generator, everything on GitHub, code and prose interleaved. That’s how ML content is made now. It’s a good stack. I’m not using it.

    I’m writing the whole thing in LaTeX — every chapter, every figure, every equation. In 2026, for a machine learning book, this is a slightly eccentric choice, and people ask why. Here’s the honest answer.

    The math has to be beautiful, because the math is the point

    The book is called Machine Learning from Scratch. The entire premise is deriving things — backpropagation by hand, gradients written out term by term, the chain rule crawling across half a page. This is not a book where equations are decoration you could screenshot from a paper. The equations are the content.

    Nothing typesets math like LaTeX. Not “renders it acceptably” — typesets it, with the spacing and alignment and typographic care that makes a three-line derivation readable instead of intimidating. Markdown with a math plugin gets you 80% there and then abandons you exactly where it matters: the aligned multi-line derivation, the numbered equation you reference twelve pages later, the matrix that has to line up. For a book that lives or dies on whether a reader can follow the math, 80% is a failing grade.

    A book is not a website

    Notebooks and Markdown optimize for the web: scrollable, linkable, runnable. Wonderful properties — for a tutorial. But I’m writing a book, and a book is a designed physical object even when it’s a PDF. Page breaks that don’t strand a heading. Figures that sit where the eye expects them. A table of contents, an index, cross-references that know their own page numbers. Consistent typography across three hundred pages.

    LaTeX was built for exactly this — it’s a typesetting system that happens to accept text input, not a text format that happens to produce output. Every serious textbook you learned from was probably set in TeX. There’s a reason the convention held.

    Plain text ages well

    My manuscript is a folder of .tex files. I can grep it, diff it, version it in Git, back it up anywhere, and open it in any editor on any machine for the next forty years. No proprietary format, no cloud account that might sunset, no notebook JSON that turns into a merge-conflict nightmare the moment two edits touch the same cell. When you’re committing to a multi-year project, “will I be able to open this in 2040” is not a paranoid question. LaTeX’s answer is yes, trivially.

    The honest catch

    I won’t pretend it’s free. LaTeX has a real learning curve, the error messages read like threats, and the edit-compile-look loop is slower than a live-rendering Markdown preview. For a quick tutorial or a runnable notebook, the modern stack genuinely wins — I’d use it without hesitation.

    But for a math-dense book meant to last, the tradeoffs run the other way, and the friction is worth paying down rather than avoiding. Which — full disclosure — is the thread that connects the two things I spend my time on: the book pushed me to sharpen the editor I write it in, and the editor is the reason the friction is bearable. The manuscript and the tool grew up together. Neither would exist in its current form without the other.

    So: LaTeX, in 2026, for a machine learning book. Eccentric, maybe. But every time a derivation lands clean on the page — spacing right, alignment perfect, reference resolved — I remember exactly why.


  • You wrote \begin{figure}[h]. You meant it. Here, you said. Put the figure here, where I have placed it, next to the sentence that refers to it, like a reasonable person arranging a reasonable document.

    LaTeX read your [h], considered it, and put the figure on the next page. Alone. Centered in an ocean of white space. Three paragraphs away from the text that mentions it.

    Welcome to floats. Everyone who has written a thesis has stood exactly where you are standing.

    The bargaining begins

    The escalation is always the same, and every LaTeX user has climbed its rungs in order:

    • [h] — “here.” A polite request. Ignored roughly half the time.
    • [h!] — “here, and I mean it.” The ! tells LaTeX to drop its rules about how much of a page a float may occupy. Stronger. Still a suggestion.
    • [ht] — “here, or top, I’m flexible.” You have started negotiating.
    • [htbp] — “here, top, bottom, or a whole page — anywhere, please, I’m begging you.” The full surrender. You are no longer specifying placement; you are listing every place you would accept.
    • \usepackage{float} then [H] — the nuclear option. Capital H means “HERE. Not a float anymore. Nail it to this exact spot and let the consequences fall where they may.”

    By the time you reach [H] you have stopped writing a paper and started fighting a typesetting engine at 1 a.m. And [H] usually “works,” which is exactly why it’s dangerous — it wins the battle and quietly wrecks the layout, leaving half-empty pages behind it like a toddler who insisted on carrying the plates.

    Why LaTeX does this to you

    Here is the part that turns the rage into grudging respect: LaTeX is not being difficult. It’s being principled.

    A float is called a float because it is designed to move. The whole point is that figures and tables should never leave an ugly gap at the bottom of a page, never get split across a page break, never strand two lines of a paragraph alone. When you write [h], you’re asking LaTeX to honor your placement and its typographic conscience at the same time — and when those conflict, it sides with the conscience. It would rather move your figure than let your document look bad by the standards of professional book typesetting.

    Word would have just jammed the image where you dropped it and let the text flow into a mess around it. LaTeX refuses. It’s the difference between a tool that does what you say and a tool that does what you meant — and the gap between those two is where all the swearing lives.

    The actual advice

    After enough theses, you stop fighting and learn the moves that actually help:

    • Use [tbp] as your default and let figures live at the top of a page. Papers look better this way than with figures wedged mid-paragraph, and once you accept it, the fighting stops.
    • Reserve [H] for the rare figure that genuinely must sit at one spot — a step in a sequence, a figure inside a boxed example. Not for every plot.
    • Reach for \clearpage before a section if floats are piling up and drifting into the wrong part of the document.
    • Trust the reference, not the position. That’s what \ref{fig:...} is for — the reader follows “Figure 3” to wherever Figure 3 landed. They do not need it glued to the sentence. Only you do, and only because you can see the source.

    The one thing that actually helps at 1 a.m.

    Most float rage comes from a slow feedback loop: change [h] to [htbp], recompile, hunt through the PDF for where the figure went this time, repeat. The faster you can see the result, the less it feels like a fight and the more it feels like nudging.

    Which is, honestly, half of why I built texspark: hit ⌘B, watch the PDF update beside the source, and forward-search to the figure to see exactly where it settled — without losing your place. Floats will still float. But you can watch them do it, and course-correct in seconds instead of minutes. It doesn’t make LaTeX obey you. Nothing does. It just makes the negotiation faster.

    The figure is on the next page again. It’s fine. Write \ref{} and let it go.


  • Abstract comparisons are easy to write and easy to ignore. So let’s make it concrete.

    The setup: a book project. main.tex at the root, ten chapters under chapters/, each pulled in with \include. You’re deep in chapters/04-optimization.tex when you want to (a) build, (b) find your place in the structure, and (c) move between source and PDF in both directions. Bread-and-butter thesis work.

    I used Texmaker for over ten years — dissertation, papers, lectures — so what follows is not guesswork about a rival. It’s muscle memory, written down.

    Round 1: Building from a sub-file

    Texmaker. Press F1 (Quick Build) while editing 04-optimization.tex and Texmaker builds that file — which promptly fails, because a chapter fragment has no preamble. The fix is the master document mechanism: Options → Define Current Document as ‘Master Document’. Do this once per session opening — it’s a mode you enable, and if you forget, your first build of the day fails first. (There’s also “restore previous session,” which helps, but the master state has a way of needing re-declaration at the worst moments.)

    texspark. Mark main.tex as the build target once — ⌘⇧P, or double-click its tab; it gets a 🔨 icon. From then on, ⌘B from any chapter builds main.tex. The target survives relaunch with the session. And if you open the project through the PDF side (more on that below), the build target sets itself.

    The difference isn’t capability — both editors can build the right file. It’s that one asks you to remember a mode, and the other asks you to make one decision, once.

    Round 2: The outline

    Texmaker. The Structure panel shows the sections of open files, per file. It goes down to subsubsection — a hierarchy depth I know precisely, because I once patched the source to add \paragraph support. To see chapter 7’s structure, chapter 7 must be open; the panel won’t walk the \include chain from main.tex and assemble the book for you.

    texspark. The outline is project-wide by construction: it parses the build target and follows every \input/\include recursively, presenting one tree in document order — chapters you haven’t opened included. It reads live buffers, so unsaved edits appear immediately; commented-out sections don’t. Click any entry and the right file opens at the right line.

    For a 200-page manuscript, this is the difference between “the outline is where I navigate the book” and “the outline is where I navigate the file I already found.”

    Round 3: Jumping between source and PDF — both directions

    Source → PDF (forward search)

    Texmaker. The built-in viewer supports forward search, and it works — from the current file to the corresponding PDF position, provided the master document is set and SyncTeX data exists. From a sub-file, the jump resolves against the master’s PDF, which is the right behavior when the mode is on.

    texspark. ⌘⇧↩ from anywhere — main file or chapter twelve — scrolls the PDF to your cursor’s line and flashes a yellow pulse there for about a second and a half, so your eye lands with your click. The same forward jump also fires when you click an outline entry or an issue row, and if the right panel happens to be showing the AI chat, it flips back to the PDF first. One more detail for long builds: the PDF’s scroll position survives multi-pass rebuilds, so a xelatex → makeindex → xelatex cycle doesn’t fling you back to page one before the jump.

    PDF → source (inverse search)

    Texmaker. Click in the viewer and you land in the source, including into included files, as long as the file is (or gets) open and SyncTeX data is present. Serviceable, occasionally moody about which window gets focus.

    texspark. ⌘-click in the PDF lands on the matching line, opening the sub-file as a tab if needed. Then the detail I’m proudest of: if you jumped into a sub-file, its parent automatically becomes the build target. The app infers the project root from where you came from — so the very next ⌘B does the right thing without you having declared anything at all.

    Round trip, in practice: pulse to the PDF, ⌘-click back into whatever chapter needs fixing, ⌘B, and the right book rebuilds. No mode, no declaration, no “wait, which file am I building.”

    The scorecard

    Honest totals: Texmaker does all three jobs. It did them for me for a decade, through a dissertation and every paper since. But each job carries a small tax — declare the master again, open the file to see its structure, mind the focus. Ten years of small taxes is what texspark was built to refund.

    If your projects are one file long, genuinely: either editor, and Texmaker is free. If your main.tex is a table of \includes — try the 14-day trial at texspark.io and build from a sub-file on day one. That single ⌘B is the whole pitch.