CLI
The mirror CLI, its commands, and their arguments.
The CLI is the tool behind the other three deliverables: it scaffolds the config, compiles the token set, generates the utility stylesheet, and places the file the Figma plugin reads. It reads one config file, writes everything into one directory, and keeps no other state.
pnpm mirror <command>
Nothing here prompts and nothing here writes state of its own. Both build
commands read mirror.config.ts from the directory they run in, and stop with
an error naming that directory if there is none.
mirror init
pnpm mirror init
This writes a mirror.config.ts that extends ours, which is the smallest
config that runs.
import { extendMirrorConfig } from '@maas/mirror'
export default extendMirrorConfig({
source: { type: 'git', repo: 'magicasaservice/mirror-tokens' },
})
The file is yours from there on, so a second run leaves an existing one alone
and says so. Pass --force to overwrite it.
Starting from your own tokens
The config above downloads the token repository on every build. To edit the
tokens, run mirror init --tokens: it copies the token tree into ./tokens
and writes a mirror.config.ts whose source reads that directory.
pnpm mirror init --tokens
import { extendMirrorConfig } from '@maas/mirror'
export default extendMirrorConfig({
source: { type: 'local', path: './tokens' },
})
Check ./tokens in with the rest of the project. Every machine and every CI
runner then resolves the same relative path, and mirror tokens compiles the
files on disk rather than fetching a ref somebody else can move.
Pass --from to copy a repository of your own rather than ours, and --dir to
land the tree somewhere other than ./tokens.
pnpm mirror init --tokens \
--from github:acme/design-tokens/packages/tokens#v3 \
--dir ./design/tokens
That copies packages/tokens out of acme/design-tokens at v3 into
design/tokens, and the config it writes reads ./design/tokens. Nothing
records where the tree came from; from here on it lives in your own repository.
Both writes refuse without --force, and both are checked before the download
starts, so a run that cannot finish downloads nothing. An empty token directory
counts as absent; a directory holding anything at all is yours and is left
alone.
mirror tokens
pnpm mirror tokens
This compiles the token source into .maas/tokens/, one directory per
platform. A Git source is downloaded into <dist>/.temp first and removed
again once the build is through, and a local source is read where it lies.
If the project root holds a figma.config.json, the run copies it into the
output directory, so dropping that directory into the Figma plugin hands it
the tokens and its own configuration in one piece.
Which platforms build and where the tokens come from are both
mirror.config.ts decisions. See Configuration.
mirror css
pnpm mirror css
This reads the compiled tokens and writes .maas/tailwind.preset.css, steered
by two keys under utilities.
utilities.variables decides which compiled tree is read, and defaults to
true. Left on, the generator reads application.variables.js, whose leaves
are var(--app-*) strings, so the emitted utilities point at custom
properties. Turned off, it reads application.js, whose leaves are resolved
colours, and the utilities end up with literals.
We recommend leaving it on, since utilities that point at custom properties are what makes cascade theming work at all. A literal cannot be overridden by loading another file, so a preset built with it off ignores every theme override, dark mode included, and the generator prints a warning to that effect on every run.
utilities.targets names the compiled targets the generator reads, in
precedence order, and defaults to ['application'].
utilities: {
variables: true,
targets: ['application'],
}
Arguments
Both build commands take the same two.
A Git source is written as a provider prefix and a repository, optionally
followed by a directory inside it and by # and a ref.
Anything starting with one of github, gitlab, bitbucket or sourcehut
followed by a colon is a repository, anything else is a path, and an
unrecognised prefix is an error rather than a path, so a typo is reported
instead of being treated as a directory name.
Only the source is overridable from outside. Targets, platforms, dist and
utilities describe what your project builds rather than which checkout builds
it, so they stay in the file where they can be reviewed.
Further reading
- Configuration: every key of
mirror.config.ts. - Quick start: both commands in a build script.