When the ready-made classes run out, you can write your own. This page is about authoring a class. First we cover the standard options a class usually accepts (font size, paper, columns, and so on), then we build up the contents of a .cls or .sty file — identifying it with \ProvidesClass, declaring options with \DeclareOption, executing them with \ProcessOptions, and building on an existing class with \LoadClass — finishing with a complete example that extends article. For using options from the document side, see “Document class & preamble.”
Class or package?
Before writing anything, decide whether you are making a **class (.cls) or a package (.sty). A class defines the kind of document itself and is loaded exactly once**, with \documentclass; it supplies the overall skeleton and default look of a paper, a book, or a set of slides. A package, by contrast, is loaded with \usepackage — any number of them — and adds features independent of the document kind (amsmath for mathematics, graphicx for figures, and so on).
In the words of the official clsguide, the test is simple: if the feature could be used with any document class, make it a package; if not, make it a class. Want to define a whole look? A class. Want to add only a feature? A package. The authoring conventions are nearly identical either way — the commands just come in a Class flavour and a Package flavour (\ProvidesClass ↔ \ProvidesPackage, \LoadClass ↔ \RequirePackage, \PassOptionsToClass ↔ \PassOptionsToPackage).
The standard options your class accepts
Users will pass options to your class just as they would to a standard one, so at minimum you want to support the usual cast: **10pt / 11pt / 12pt for the base body size, a4paper / letterpaper for paper, onecolumn / twocolumn for columns, oneside / twoside for the printing side, and draft** (which marks overfull lines with a black bar; its opposite is final). You need not implement these yourself — as we will see under “Hand options to a base class,” the standard move is simply to forward them to a base class such as article.
| Option | Meaning | Default |
|---|---|---|
10pt / 11pt / 12pt | Base body font size | 10pt |
a4paper / letterpaper | Paper size (also b5paper, legalpaper, etc.) | letterpaper |
onecolumn / twocolumn | One column / two columns | onecolumn |
oneside / twoside | One-sided / two-sided layout | oneside (but twoside for book) |
draft / final | Whether to mark overfull lines with a black bar | final |
For worked examples of specifying and using these options on the document’s \documentclass[...] side — and book-specific ones like openright — see the sibling page “Document class & preamble.” From here on we focus on how to write the class that receives them.
Identify the file up front
The first two lines of a class file (myclass.cls) are almost boilerplate. First, **\NeedsTeXFormat{LaTeX2e} declares that the file is meant for LaTeX2e (loading it under an older format triggers a warning). Then \ProvidesClass{myclass}[2026/01/01 v1.0 ...] announces the class name, release date, version, and a short description. The bracketed part is optional, but supplying it lets users request a minimum version via the date (in YYYY/MM/DD form)** — \documentclass{...}[2026/01/01] — and records the identification in the log.
If you are writing a package, the counterpart is **\ProvidesPackage{mypackage}[2026/01/01 v1.0 ...]**; \NeedsTeXFormat is shared by both. As a firm rule, the **name in \ProvidesClass / \ProvidesPackage must match the actual file name** — inside myclass.cls, you always write \ProvidesClass{myclass}.
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]Declaring options — \DeclareOption
You declare each option your class accepts with **\DeclareOption{option}{code}. When the user specifies that option, its code** runs at the moment \ProcessOptions is reached (described below). For instance, you might provide your own draft switch that sets a boolean flag.
The catch-all for options you did not declare is the starred form **\DeclareOption*{code}. Inside it, \CurrentOption expands to the name of the option currently being processed. The single most common line in a custom class forwards** any unknown option straight to the base class. Thanks to it, users can pass standard options like 10pt or a4paper as a matter of course, even though you never declared them yourself.
% pass anything we do not handle ourselves on to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}In a package you use the equivalent **\PassOptionsToPackage{\CurrentOption}{base}**. If you want to apply defaults before \ProcessOptions, write **\ExecuteOptions{a4paper,11pt}** — that runs the code for those options first, so they take effect even when the user specifies nothing.
Process options, then hand off to a base class
Declaring options does nothing on its own; their code runs only when you call **\ProcessOptions. In practice you almost always write \ProcessOptions\relax**. Because a starred form \ProcessOptions* also exists, the trailing \relax is the idiom that reliably selects the unstarred one. Unstarred \ProcessOptions handles options in the order you declared them; the starred form handles them in the order the caller specified.
Building a layout from scratch is a lot of work, so most custom classes stand on an existing one. That is **\LoadClass[options]{article}**, which pulls in all of article.cls’s commands and styling (you may pass twocolumn and friends in the brackets). **\LoadClass may be used only inside a class file.** Order matters: so that the options the user gave on \documentclass[...] reach the base class, **put \LoadClass after option processing (\ProcessOptions).** Set up forwarding first, let \ProcessOptions dispatch the options, and only then load the base.
If you simply want to give the base class the very same options your class received, **\LoadClassWithOptions{article} is handy (it forwards the class’s global options as-is). When writing a package, use \RequirePackage** instead of \LoadClass (it is the author’s equivalent of \usepackage in the preamble), and **\RequirePackageWithOptions** for the pass-everything-through case.
Everything after \LoadClass is where the character of your class finally goes: redefine heading styles with \renewcommand, adjust margins with \setlength, define new commands and environments via \newcommand / \newenvironment — and load any extra packages you need with \RequirePackage from here.
A complete minimal class extending article
Putting it all together gives this minimal .cls. It builds on article, adds its own draft option, forwards unknown options to article, and finally tidies the margins and defines one command of its own. Save it as myclass.cls and use it from a document with \documentclass[11pt,a4paper]{myclass}.
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]
% --- declare options ---
\newif\ifmy@draft
\DeclareOption{draft}{\my@drafttrue}
% forward everything else to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
% --- execute and load the base class ---
\ExecuteOptions{a4paper} % a default if the user gives none
\ProcessOptions\relax
\LoadClass{article}
% --- this class's own setup ---
\RequirePackage[margin=25mm]{geometry}
\setlength{\parindent}{0pt}
\newcommand{\version}{v1.0}
\ifmy@draft \RequirePackage{draftwatermark}\fi
\endinputThe closing **\endinput** tells LaTeX to read no further from this file; it is conventional to include it. To make a package instead, swap the opening for \ProvidesPackage and \LoadClass for \RequirePackage: the same skeleton becomes a .sty file.
The modern way: key–value options (expl3)
The \DeclareOption mechanism above remains perfectly valid, but it is built mainly around on/off switch-style options. For new code that wants natural key–value options like name=value, the current recommendation is the LaTeX kernel’s own interface: declare keys with **\DeclareKeys and process them with \ProcessKeyOptions**. Built on expl3 (LaTeX3)’s l3keys, it ships as part of recent LaTeX kernels.
This used to be done with the **l3keys2e** package, but the core of that functionality is now folded into the kernel, so new code can call \ProcessKeyOptions directly without loading the package. That said, existing tutorials and many packages still center on the \DeclareOption style, so understanding this page’s skeleton remains valuable. When you move to key–value options, consult the relevant section of the current clsguide (“LaTeX2e for class and package writers”).