Skip to content

lyrn new

Terminal window
$ lyrn new <name> [options]

Creates a project in a directory named after it, or wherever --path points. The destination has to be empty or absent — lyrn never writes into a directory that already holds something.

Lowercase letters, digits and hyphens, starting with a letter. That is the strictest of what a directory, a crate and an npm package can each be called, so a name lyrn accepts works in all three:

Terminal window
$ lyrn new Demo App
error: the name starts with `D`; it has to start with a lowercase letter
Option Default What it does
--form <form> spa The shape of the project; see Forms
--accent <colour> asked, else graphite A product of the line, or a #rrggbb value
--description <text> asked, else generic One line describing what the project is
--author <name> git config user.name Recorded in LICENSE
--path <path> ./<name> Where to create it
--repo <owner/name> looked up The GitHub repository it will live in
--with <addon,...> none Optional pieces, per form; see Forms
-y, --yes Accept the defaults instead of asking
--dry-run Show what would be written, and write nothing
--no-hooks Skip installing dependencies and starting the repository

--accent takes either a colour or the name of a product on the line, in which case that product’s mark supplies the colour:

Terminal window
$ lyrn new demo-app --accent kilna # the mark's magenta
$ lyrn new demo-app --accent '#3fa873' # a colour of your own

It lands in src/styles.css as a single declaration, and the dowel theme derives the rest from it:

:root {
--accent-base: #d9569e;
}

A project with no mark of its own yet gets neutral graphite — a placeholder that reads as “this has not been drawn yet”. lyrn.toml records which of the two happened:

[project]
accent = "#6E7079"
mark = "placeholder" # or `chosen`, once the product has a mark

Naming an accent is what choosing a mark looks like from here — it is the one thing lyrn new learns about a product’s identity, and the whole palette is derived from it. Giving the placeholder’s own hex explicitly still counts as unmarked, so nothing is quietly promoted.

On the desktop form the placeholder is visible rather than implied: the application icon is the line’s umbrella mark until you replace it. See the desktop form.

Installers, the npm wrapper and the update check all need to know where the project lives. The owner is looked up rather than derived from a name: a GitHub account is not a person’s name, and turning “Jane Smith” into jane-smith produces a URL that looks right and resolves to nobody. lyrn reads git config github.user, then the account gh is logged in as; with neither, it writes OWNER - visibly a blank rather than a plausible mistake.

Terminal window
$ lyrn new my-tool --form cli --repo myorg/my-tool

--with takes the optional pieces of a form, comma-separated. What is on offer depends on the form, and lyrn forms lists them underneath it:

Terminal window
$ lyrn new my-tool --form cli --with keyring,self-update

An add-on a form does not have is an error rather than a silent no-op.

A form decides what an add-on means for it. --with i18n on a desktop project also writes the locale gate into pnpm lint; on a spa it writes the same runtime without the desktop shell around it.

After the files are written, lyrn fetches what the project depends on - pnpm install or cargo fetch, whichever the form uses - and starts the repository with one Conventional Commit. Both are skipped by --no-hooks, and a missing tool is reported rather than fatal: the files are already on disk and the step is one command away.