# Is it possible to "relocate" my ~/texmf/ directory?

My custom `sty` files are stored in the `~/texmf/` directory. I like to keep the contents of my home directory simple, so I'd like to move `~/texmf/` somewhere else (maybe `~/.texmf/` or `~/.config/texmf/`). Is this possible?

• `export TEXINPUTS=/pathtomyothertexmfdirectory:\$TEXINPUTS` perhaps, assuming you're using bash
– user31729
Dec 29, 2018 at 18:55
• the TEXINPUTS environment variable is exactly meant for such cases when the input files are spread over the whole file system...
– user31729
Dec 29, 2018 at 19:32
• @ChristianHupfer Will that command permanently change the environment variable? Dec 29, 2018 at 19:42
• Yes. You can store the old version first in a backup environment variable and restore it later on, if needed. I assume that you don't want to type the command each time you're logged into your computer, so I suggest to use your local `.bashrc` in order to keep store the command there. This way, you can easily remove the path later on, if you don't like it any longer
– user31729
Dec 29, 2018 at 19:45
• @ChristianHupfer That won't work, but `export TEXINPUTS=/path/to/the/desired/place//:` might be a substitute. Not the best way to do that, though. Dec 29, 2018 at 21:45

If you issue the shell command

``````cat \$(kpsewhich texmf.cnf)
``````

(`bash` syntax, adapt to your shell way to do command substitution) you should see

``````% (Public domain.)
% This texmf.cnf file should contain only your personal changes from the
% original texmf.cnf (for example, as chosen in the installer).
%
% That is, if you need to make changes to texmf.cnf, put your custom
% settings in this file, which is .../texlive/YYYY/texmf.cnf, rather than
% the distributed file (which is .../texlive/YYYY/texmf-dist/web2c/texmf.cnf).
% And include *only* your changed values, not a copy of the whole thing!
%
TEXMFHOME = ~/texmf
TEXMFVAR = ~/texlive/2018/texmf-var
TEXMFCONFIG = ~/texlive/2018/texmf-config
``````

(this is what you get on standard Unix boxes, there is `/Library` after `~` with the MacTeX version of TeX Live).

If the start of the file you get is different, namely

``````% original texmf.cnf -- runtime path configuration file for kpathsea.
``````

then your system doesn't have a top level `texmf.cnf` file. No problem.

All it takes is to launch

``````sudo nano \$(kpsewhich -var-value TEXMFROOT)/texmf.cnf
``````

(use whatever method you use for getting superuser privileges and whatever editor you prefer). If you are in the no-top-level-`texmf.cnf` situation, you will see an empty file.

Add or change the `TEXMFHOME` line to what you wish. Perhaps also the other lines, if you also want to move `texlive` to a hidden place.

Then rename or move the relevant directories to the correct place.

Explanation. The file resides at the top level of the TeX Live distribution, namely at

``````/usr/local/texlive/2018/texmf.cnf
``````

and it is the first configuration file read by `kpse` library linked programs (all those in the TeX family); other files with the same name are read in during initialization, but values of (pseudo)enviroment variables are never overridden by subsequent files. Setting personal preferences in that file is actually the recommended method.

• Side note: I'm surprised it's this difficult to do this! Dec 30, 2018 at 1:42
• @ Well, at least in a default in Linux installation of the vanilla TeXLive2018 that file only will have the comments, making for a novice still harder figure out what the hell is this file for and what you can do here, but if you read carefully the comments is not so hard, except know that that file exists. :(
– Fran
Dec 30, 2018 at 10:03
• @BrianFitzpatrick It's not really so difficult; you might ask the maintainers of TeX Live if they want to make this doable at installation time. An obvious problem with multiuser boxes is that once you do that all other users have to follow suit. Dec 30, 2018 at 10:57
• Nicer answer @egreg but not completely true. The texmf.cnf in 2018/ does not contain entries for TEXMFHOME, but only for TEXMFLOCAL. So one would need to add a line `TEXMFHOME = ....` and save. Also, one might end up editing the main texmf.cnf file in texmf-dist/web2c/ if there is no file 2018/texmf.cnf, so better would be: "Edit or create a file \$(kpsewhich -var-value TEXMFROOT)/texmf.cnf and add a line for TEXMFHOME there. Dec 31, 2018 at 0:37

I had written most of this answer more or less a month ago, but I hadn’t found the time to complete it until now.

Elaborating on what I’ve already said in a comment, in my humble opinion the best way to achieve literally what the question asks for depends on whether you are a generic, unprivileged user trying to relocate just your own `~/texmf/` directory, or an administrator who wants to set a different location for the `~/texmf/` directory of all users of a given host.

## Generic user who wants to relocate only her/his own directory

Add a line to your `.profile`, `.bashrc`, or whatever configuration file your shells reads during initialization a line that creates an environment variable (not just a shell variable) named `TEXMFHOME` and sets its value to the path that should be used instead of `~/texmf`. For example, for a Bourne shell you might add to your `.bashrc` file a line that says

``````export TEXMFHOME='~/.some/hidden/place/texmf'
``````

(note that quoting has been used to prevent tilde expansion from being applied by the shell itself).

## Administrator who wants to relocate all users’ directories

Let’s assume that your TeX Live distribution for 2018 is located in

``````/some/path/to/texlive/2018
``````

which amounts to saying that the above path is what you get in reply to the command

``````kpsewhich -var-value TEXMFROOT
``````

(normally, the reply to this command will be

``````/usr/local/texlive/2018
``````

which amounts to saying that the above path is where TeX Live 2018 is normally installed on Unix-like systems); then, the parent directory

``````/some/path/to/texlive
``````

is likely to contain other subdirectories, one for each distribution of a previous year you are still retaining, plus one additional subdirectory named `texmf-local` (for example, on my machine, the directory

``````/usr/local/texlive
``````

contains the following subdirectories

``````2014/
2015/
2016/
2017/
2018/
texmf-local/
``````

with old distributions going back to that of 2014). In any case, acquire root privileges and create a (text) file with full pathname

``````/some/path/to/texlive/texmf-local/web2c/texmf.cnf
``````

also creating, if necessary, any missing directory along the path (for example, on the machine I’m using now I’d create a file with full pathname

``````/usr/local/texlive/texmf-local/web2c/texmf.cnf
``````

but on some other machine of mine I wouldn’t need to, because I already did so a few years ago). Open that file for editing and write the following line into it:

``````TEXMFHOME = ~/.some/hidden/place/texmf
``````

Save the file. That’s all: TeX Live will now look inside `~/.some/hidden/place/texmf/` (and the sub-sub-…-directories thereof) for anything it would have previously searched inside `~/texmf/` (and the sub-sub-…-directories thereof). Don’t forget to instruct users to move their personal texmf tree in the new location!

Following this strategy, you won’t need to reapply your customization every time you switch to a new distribution—that is, every year—which, as I remarked in a comment, is a small drawback of the other answer. Indeed, you might want to add other lines to your new file

``````/some/path/to/texlive/texmf-local/web2c/texmf.cnf
``````

in order to specify some other customization you want to apply on a “all-user, all-year” basis; for example, on some machines (not on this one) I keep, as I’ve already said, a file

``````/usr/local/texlive/texmf-local/web2c/texmf.cnf
``````

which contains the line

``````file_line_error_style = t
``````

(possibly among others).

This strategy too, however, is not immune from defects, which are discussed in the longer answer that follows.

The path to the root of the “personal” texmf tree, or, more precisely, the value of `TEXMFHOME`, is specified (of course!) in the same way as any other path, that is, as documented in the Kpathsea manual, Section 5.2 Path Sources, by looking it up in the following sources of information:

1. A user-set environment variable, e.g., `TEXINPUTS`. Environment variables with an underscore and the program name appended override; for example, `TEXINPUTS_latex` overrides `TEXINPUTS` if the program being run is named `latex`.

2. A program-specific configuration file, e.g., an `S /a:/b` line in Dvips’ `config.ps` (see Config files in Dvips).

3. A line in a Kpathsea configuration file texmf.cnf, e.g., `TEXINPUTS=/c:/d` (see below).

4. The compile-time default (specified in `kpathsea/paths.h`).

These sources are queried in turn, in the stated order, and earlier definitions override later ones; moreover, a higher-priority source can “import” a lower-priority one via a mechanism known as “Default Expansion”, which we are not going to describe here (interested readers are referred to Subsection 5.3.1 Default Expansion of the above-cited manual)

Given the above information, you may think that the easiest way to achieve what the question asks for is, perhaps, to set (and export) an environment variable named `TEXMFHOME` in your `.profile`/`.bashrc`/etc. file. There are some caveats, though:

• The configuration files in the TeX Live distribution define a few other path variables that should be kept “in sync” with `TEXMFHOME`, but that, notwithstanding this, are not defined in terms of the latter; for example, on my machine (a Mac with MacTeX installed), the file located at

``````/usr/local/texlive/2018/texmf.cnf
``````

``````% (Public domain.)
% This texmf.cnf file should contain only your personal changes from the
% original texmf.cnf (for example, as chosen in the installer).
%
% That is, if you need to make changes to texmf.cnf, put your custom
% settings in this file, which is .../texlive/YYYY/texmf.cnf, rather than
% the distributed file (which is .../texlive/YYYY/texmf-dist/web2c/texmf.cnf).
% And include *only* your changed values, not a copy of the whole thing!
%
TEXMFHOME = ~/Library/texmf
TEXMFVAR = ~/Library/texlive/2018/texmf-var
TEXMFCONFIG = ~/Library/texlive/2018/texmf-config
``````

Obviously, `TEXMFVAR` and `TEXMFCONFIG` should be kept “synchronized” with `TEXMFHOME`. (At this point, the attentive and knowledgeable reader has probably already spotted the source of the trouble…)

• You might want to consider quoting the values assigned to environmental variables within a shell script in order to prevent premature expansion by the shell itself.

Following this line of thought, the next option is, of course, to have the desired value of the `TEXMFHOME` (and, one might feel inclined to add, of the other “synchronized” variables, `TEXMFVAR` and `TEXMFCONFIG`) specified in a configuration file, which, in this case, can only be one of the several `texmf.cnf` files. We say “the several” because the Kpathsea library can read more than one such file, and actually does so in typical situations. Quoting from Subsection 5.2.1 Config files of the manual,

[…] Kpathsea reads runtime configuration files named `texmf.cnf` for search path and other definitions. The search path used to look for these configuration files is named `TEXMFCNF`, and is constructed in the usual way, as described above [items 1–4], except that configuration files cannot be used to define the path, naturally; also, an `ls-R` database is not used to search for them.

Kpathsea reads all `texmf.cnf` files in the search path, not just the first one found; definitions in earlier files override those in later files. […]

In practice, the first of the two paragraphs just quoted means that `TEXMFCNF` (which, we repeat, is the search path for the configuration files themselves) is defined either in an environmental variable, or by the compile-time default. Let the former alternative alone, and let’s concentrate on the search path specified at compile-time: as the manual says, this is defined in `kpathsea/paths.h`; inspecting that file, we find that the definition of `DEFAULT_TEXMFCNF` reads (I’ve broken it up into separate lines for readability):

``````#ifndef DEFAULT_TEXMFCNF
#define DEFAULT_TEXMFCNF "{\$SELFAUTOLOC,\
\$SELFAUTOLOC/share/texmf-local/web2c,\
\$SELFAUTOLOC/share/texmf-dist/web2c,\
\$SELFAUTOLOC/share/texmf/web2c,\
\$SELFAUTOLOC/texmf-local/web2c,\
\$SELFAUTOLOC/texmf-dist/web2c,\
\$SELFAUTOLOC/texmf/web2c,\
\$SELFAUTODIR,\
\$SELFAUTODIR/share/texmf-local/web2c,\
\$SELFAUTODIR/share/texmf-dist/web2c,\
\$SELFAUTODIR/share/texmf/web2c,\
\$SELFAUTODIR/texmf-local/web2c,\
\$SELFAUTODIR/texmf-dist/web2c,\
\$SELFAUTODIR/texmf/web2c,\
\$SELFAUTOGRANDPARENT/texmf-local/web2c,\
\$SELFAUTOPARENT,\
\$SELFAUTOPARENT/share/texmf-local/web2c,\
\$SELFAUTOPARENT/share/texmf-dist/web2c,\
\$SELFAUTOPARENT/share/texmf/web2c,\
\$SELFAUTOPARENT/texmf-local/web2c,\
\$SELFAUTOPARENT/texmf-dist/web2c,\
\$SELFAUTOPARENT/texmf/web2c}"
#endif
``````

Indeed, this corresponds exactly to what I get on my machine if I issue the shell command

``````kpsewhich -var-value TEXMFCNF
``````

The answer I get is (again, split up into lines for readability):

``````{/usr/local/texlive/2018/bin/x86_64-darwin,
/usr/local/texlive/2018/bin/x86_64-darwin/share/texmf-local/web2c,
/usr/local/texlive/2018/bin/x86_64-darwin/share/texmf-dist/web2c,
/usr/local/texlive/2018/bin/x86_64-darwin/share/texmf/web2c,
/usr/local/texlive/2018/bin/x86_64-darwin/texmf-local/web2c,
/usr/local/texlive/2018/bin/x86_64-darwin/texmf-dist/web2c,
/usr/local/texlive/2018/bin/x86_64-darwin/texmf/web2c,
/usr/local/texlive/2018/bin,
/usr/local/texlive/2018/bin/share/texmf-local/web2c,
/usr/local/texlive/2018/bin/share/texmf-dist/web2c,
/usr/local/texlive/2018/bin/share/texmf/web2c,
/usr/local/texlive/2018/bin/texmf-local/web2c,
/usr/local/texlive/2018/bin/texmf-dist/web2c,
/usr/local/texlive/2018/bin/texmf/web2c,
/usr/local/texlive/texmf-local/web2c,
/usr/local/texlive/2018,
/usr/local/texlive/2018/share/texmf-local/web2c,
/usr/local/texlive/2018/share/texmf-dist/web2c,
/usr/local/texlive/2018/share/texmf/web2c,
/usr/local/texlive/2018/texmf-local/web2c,
/usr/local/texlive/2018/texmf-dist/web2c,
/usr/local/texlive/2018/texmf/web2c}
``````

Let’s spend a couple of minutes to understand exactly why the above two listings agree, because something important is involved here.

First of all, I haven’t set `TEXMFCNF` in my environment, so what I’m getting is indeed the compile-time default. (Note: As a matter of fact, this is not true, because the main `texmf.cnf` file of TeX Live, that is, `/usr/local/texlive/2018/texmf-dist/web2c/texmf.cnf`, actually redefines the `TEXMFCNF` variable; but it is a white lie, since this redefinition agrees completely with the compile-time default.) That being said, the key point is to understand how the (pseudo-?) variables `SELFAUTOLOC`, `SELFAUTODIR`, `SELFAUTOPARENT`, and `SELFAUTOGRANDPARENT` are interpreted; their meaning is always relative to the position of the executable file that has invoked the Kpathsea library (e.g., `pdftex`, `pdflatex`, `tex`, but also `kpsewhich`); more precisley:

• `SELFAUTOLOC` expands to the path to the directory that contains the executable;

• `SELFAUTODIR` expands to the parent directory of the directory that contains the executable;

• `SELFAUTOPARENT` expands to the parent directory of the parent directory of the directory that contains the executable;

• `SELFAUTOGRANDPARENT` expands to the parent directory of the parent directory of the parent directory of the directory that contains the executable.

A bit confusing, isn’t it? It’s better to use an example: let’s say that the executable file resides inside

``````/usr/local/texlive/2018/bin/x86_64-darwin/
``````

(as it is on my machine); then:

• `SELFAUTOLOC` expands to

``````/usr/local/texlive/2018/bin/x86_64-darwin
``````
• `SELFAUTODIR` expands to

``````/usr/local/texlive/2018/bin
``````
• `SELFAUTOPARENT` expands to

``````/usr/local/texlive/2018
``````
• `SELFAUTOGRANDPARENT` expands to

``````/usr/local/texlive
``````

(Much clearer, I’d say.) You can now return to the two listings given above, and amuse yourself by checking that each line of the first expands precisely to its corresponding line in the second.

Note an important detail: being relative to the location of the executable, the above expansions work correctly even if the whole texmf tree is moved to a different location (perhaps on a removable media, like a USB stick).

Armed with this knowledge, let’s focus on the particular use that the TeX Live distribution makes of all this machinery. Usually, only two items of the compile-time default are exploited by TeX Live, namely

``````\$SELFAUTOPARENT
``````

and

``````\$SELFAUTOPARENT/texmf-dist/web2c
``````

The latter is the “original” `texmf.cnf` file being distributed; the former (that, remember, takes precedence) is provided to allow host-specific customization. By way of example, the MacTeX distribution uses the `\$SELFAUTOPARENT` entry to customize the location of the personal texmf tree (`TEXMFHOME`), moving it inside the `Library/` subdirectory of the user’s home folder. This may make this file look like the natural place to turn to in order to solve the OP’s problem, as @egreg has already suggested; but there are a couple of issues you should be aware of:

1. This solution (as any other based on configuration files) applies on a per-host basis, that is, to all users of a given machine.

2. Because `SELFAUTOPARENT` expands to a directory name that embodies the year of the distribution, you’ll need to re-apply your customization when you update your distribution: indeed, in a new distribution the location of the executable will change, and, with it, the value of `SELFAUTOPARENT`.

Point 1 can be a problem or a feature, depending on the circumstances. As for point 2, a remedy is—or seems to be—readily available: if you go back to the listings extracted from `kpathsea/paths.h`, you’ll notice, among the entries that precede the two ones used by TeX Live, one that looks particularly appealing:

``````\$SELFAUTOGRANDPARENT/texmf-local/web2c
``````

which typically expands to

``````/usr/local/texlive/texmf-local/web2c
``````

(“Aha!”—you might be thinking); and indeed, this is where, sometimes (that is, on some machines, but not on this particular one), I keep a third `texmf.cnf` file, containing the patches I want to apply on a “per-host, but all-year” basis. Well, if you create a file in this location, that is, having full pathname

``````/usr/local/texlive/texmf-local/web2c/texmf.cnf
``````

and whose contents look like this

``````TEXMFHOME = ~/.SomeHiddenPlace/texmf
``````

you are changing, in the stated way, the location of the personal texmf tree of all users on your machine, and this change will be permanent across distributions. This is exactly what the title of the question asks for; however, an issue remains, that we have already touched upon above, and that proves unexpectedly difficult to solve, in full generality, by similar means.

We already remarked that there are (at least) two other paths into the personal tree that one would reasonably want to keep “synchronized” with `TEXMFHOME`, those corresponding to the two variables `TEXMFVAR` and `TEXMFCONFIG`. Their default definition (i.e., their definition in the “original” `texmf.cnf` file of TeX Live) is

``````% TEXMFVAR, where texconfig/updmap/fmtutil store cached runtime data.
TEXMFVAR = ~/.texlive2018/texmf-var

% TEXMFCONFIG, where texconfig/updmap/fmtutil store configuration data.
TEXMFCONFIG = ~/.texlive2018/texmf-config
``````

It seems reasonable that, if one wishes to convert

``````TEXMFHOME = ~/texmf
``````

into

``````TEXMFHOME = ~/.SomeHiddenPlace/texmf
``````

in the same way the same person might want to have `TEXMFVAR` and `TEXMFCONFIG` moved in parallel, in order to reduce clutter in her/his home directory:

``````TEXMFVAR = ~/.SomeHiddenPlace/.texlive2018/texmf-var
TEXMFCONFIG = ~/.SomeHiddenPlace/.texlive2018/texmf-config
``````

In the same way, under MacTeX, one might want to pass from

``````TEXMFHOME = ~/Library/texmf
TEXMFVAR = ~/Library/texlive/2018/texmf-var
TEXMFCONFIG = ~/Library/texlive/2018/texmf-config
``````

to, say,

``````TEXMFHOME = ~/Library/TeXStuff/texmf
TEXMFVAR = ~/Library/TeXStuff/texlive/2018/texmf-var
TEXMFCONFIG = ~/Library/TeXStuff/texlive/2018/texmf-config
``````

(although the motivation is much weaker in this case). The problem is that the last two directories should be kept separate in passing from one year to the next; for example, both occurences of `2018`, above, should be replaced by `2019` when the 2019 distribution of TeX Live becomes available.

## A modest proposal

A possible solution would be to define, in the `texmf.cnf` file distributed with TeX Live, a new variable that holds the year of the distribution. Let’s assume that this variable is called `YYYY`; then we could write something like

``````TEXMFHOME = ~/.SomeHiddenPlace/texmf
TEXMFVAR = ~/.SomeHiddenPlace/.texlive\${YYYY}/texmf-var
TEXMFCONFIG = ~/.SomeHiddenPlace/.texlive\${YYYY}/texmf-config
``````

in the file

``````\$SELFAUTOGRANDPARENT/texmf-local/web2c
``````

(the typical expansion of which is

``````/usr/local/texlive/texmf-local/web2c
``````

that is, the file you need not modify when you upgrade your TeX Live distribution to that of a new year) to move the specified directories under `.SomeHiddenPlace/` for all the users and all the years to come. Note that this works correctly even if the file that defines the `YYYY` variable is read by the Kpathsea library after the file where that variable is used; indeed, quoting from Section 5.2.1 of the Kpathsea manual:

All definitions are read before anything is expanded, so you can use variables before they are defined (like Make, unlike most other programs).

The TeX Live team might want to give this proposal some thought.