Why is startcmd deprecated?

Despite its popularity, the startcmd script delivered with DITA-OT has finally outlived its usefulness. This article is intended for those worried about its eventual removal. My hope is to explain why the script was created, how it was always more a way to hide problems rather than address them, and (most importantly) how Jarno Elovirta finally fixed the problems that caused us to add startcmd in the first place. Without those problems … there is no longer a need to hide them with a script.

Why you don't need startcmd: tl;dr version

  • In the first few releases, DITA-OT was complex to set up.
  • startcmd.bat (or startcmd.sh) is a kludge that hides complexity (but doesn't fix it).
  • Under the covers, Jarno Elovirta made builds simple. Without the complexity, you don't need startcmd.
  • You can still run your Ant builds. You can still call Ant directly.
  • Better, you can run the new, simple dita command. It's neat. You should try it.

DITA-OT as a (literal) toolkit

DITA Open Toolkit is a toolkit - it's there in the name. With your DITA content as the raw material, you can use DITA-OT to build pretty much anything. The basic toolkit comes stocked with tools to create XHTML, PDF, and a few other basic outputs. Plug in a few of your own tools, and possibilities are endless.

The problem with DITA-OT 1.0 was that it was like getting only part of what you need:

  • You had Ant scripts, but no copy of Ant to drive them through the process. (DITA-OT gave you the nails, but you had to provide your own hammer.)
  • You had tons of XSLT scripts, but no processor to make them work. (DITA-OT gave you plenty of screws, but you had to provide your own screwdriver.)
  • You had XSL-FO output, but no way to turn that into PDF. (A handful of nuts and bolts, with no wrench to put them together.)

Once you collected the missing tools, you had to assemble them yourself by setting up environment variables. Among other steps, the DITA-OT 1.0 installation instructions included the following:

  • Set up your XSLT processor and include the jar files needed into the CLASSPATH. For example, if you are using saxon, include saxon.jar into the CLASSPATH. If you are using xalan, include xalan.jar and xercesImpl.jar into the CLASSPATH.
  • Optional: If you have installed FOP, set up your environment variable CLASSPATH to include the jar file of fop.jar, batik.jar and avalon.jar in FOP and your xslt processor

This put the toolkit beyond the reach of many authors. (Most of those used to modifying environment variables still prefer to avoid it.) It's as if you picked up a toolkit, and opened it to find instructions on where to obtain (and assemble!) your own hammer and screwdriver.

"Start command": the magic "assemble my tools" command

The first attempt at simplification was a new bundled package that included Ant, Saxon, FOP, and more. With that package came startcmd.bat (for Windows) and startcmd.sh (for Mac or Linux). These scripts hid DITA-OT's complexity without changing how the toolkit works. They still did everything listed in the DITA-OT 1.0 install guide. And they did it over and over:

  • They set up a (temporary) environment variable with Ant options
  • They (temporarily) added DITA-OT's copy of Ant into the PATH environment variable
  • They added a list of bundled libraries to a (temporary) CLASSPATH environment variable

While the original toolkit was missing essential tools, the bundled package added those tools - but didn't tell them how to work together. Effectively, the new package put all of the previously-missing (but still disassembled) tools into secret drawers in your toolkit. startcmd was a shortcut that told DITA-OT where to find those tools and how to put them together - a process repeated every time you ran a build.

A new approach: the dita command

The dita command is a new way to call the toolkit. It has simple parameters for the most common options, and (for many builds) allows you to completely forget that the ant command ever existed. Happily, a normal build with dita also hides the hundreds of lines that previously came out for every build - from now on, you only see actual error messages. The following command runs a complete build, specifying an input file, output format, and output directory:
dita -i inputFile.ditamap -f html5 -o outputDir

Even better, thanks to brilliant work by Jarno Elovirta, dita also addresses the original toolkit problem - it eliminates the need to find or assemble tools. The toolkit is complete and ready to use; all you need to do is remember how to find it. Finally, the dita command knows where to find both the screws and the (fully functional) screwdriver.

Given the history of startcmd as the Tool That Made Builds Easy, I expect concern about its eventual removal. But at this point, what is it doing for you? The answer is … not much. It helps you find the toolkit, so you can run ant without any path. On Windows, it also opens up a new command prompt. And … that's it, really. It still sets a bunch of environment variables, but the toolkit itself no longer needs them.

Can this be helpful? Sure. Is it familiar? Absolutely. Is it necessary? No - you can do the same builds you have today from anywhere on your system, as long as you remember where you put your toolkit.

A final argument for the dita command

For any given release, startcmd only knows how to find and assemble the tools bundled with that release. If you copy startcmd and edit it to run a specific build, what happens when you run that batch script with the next version of the toolkit? If that version requires a new tool, your build will fail. If a new toolkit comes with pliers, an old batch file that can only find the hammer and screwdriver needs to change.

With dita, all that matters is that single command. When the next toolkit adds a fancy set of pliers, a batch script that calls dita still works. When a later DITA-OT requires a hacksaw, bottle opener, wire cutters, and shiny red stapler, a batch script that calls dita still works.


As familiar as startcmd might be, we shouldn't fear moving on. That script was always a kludge - an effective one, which is why it lasted so long as the normal way of doing business. But that was all it ever was - a patch that hid complexity, without addressing the complexity itself.

Thanks to Jarno’s generous work over the last couple years, that kludge is no longer necessary. We no longer need to reassemble our toolkit every time we want to build something. The tools are all there, and delivered in working order. All we need to do is tell it to build.