A TypeScript CLI that creates a TYPO3 v14 project with DDEV and a custom
sitepackage. Before optional TYPO3 extensions are selected, it asks which
developer stack to install: bootstrap_package, bootstrap_package + Vite,
fluid-styled-content, fluid-styled-content + Vite, or
fluid-styled-content + Vite + StyleX. It builds a complete
plan before it changes the
target project, so --dry-run can show the exact commands and files first.
- Node.js 20 or later
- DDEV and a running Docker provider
- Internet access for Composer, npm, and DDEV add-ons
The generated project is fixed to PHP 8.3 in DDEV, Composer's platform configuration, and the Rector template. The installer checks Node.js, DDEV, and Docker before a real installation.
These steps create a new local TYPO3 v14 project with DDEV. Before you start, install Node.js 20 or later, DDEV, and Docker, then start Docker.
-
Clone the repository and enter it:
git clone https://github.com/Starraider/TYPO3-auto-install.git cd TYPO3-auto-installIf you downloaded the repository as a ZIP from GitHub, extract it, open a terminal in the extracted
TYPO3-auto-installdirectory, and continue with the next step. -
Install the installer dependencies:
npm install
-
Confirm that Node.js, DDEV, and Docker are ready:
npm run dev -- doctor
Fix every failed check before continuing. Docker must be running.
-
Set the default values for your project in installer.config.yaml. For example, open it with:
nano installer.config.yaml
At a minimum, choose a
project.name,project.title,project.directory,sitepackage.vendor,sitepackage.name, anddeveloperStack. Use lowercase letters, numbers, and hyphens for the project name and vendor. Use lowercase letters, numbers, and underscores for the sitepackage key.Set
project.directoryto an empty directory that does not already contain a TYPO3 project. For example, use../acme-websiteto create the project beside this installer repository. Leave the database values at their DDEV defaults unless you know that your DDEV setup needs different values.Do not add the TYPO3 administrator password to this file. The installer asks for it privately. It needs at least eight characters, an uppercase letter, a lowercase letter, a number, and a special character.
-
Preview the work before any files are created:
npm run dev -- install --dry-run
Answer the interactive questions. Press Enter to accept the values from
installer.config.yaml, or replace them for this installation. The dry run prints the planned commands and makes no changes. -
Run the installer:
npm run dev -- install
Answer the same project and administrator questions. The developer-stack choice appears before the TYPO3 extension multi-select; TYPO3 Rector and Playwright remain independent optional choices. The installer then creates the project, starts DDEV, installs TYPO3 and the selected sitepackage, and configures the applicable tools.
-
Open the URL printed at the end of the installation, usually:
https://<project-name>.ddev.siteSign in to the TYPO3 backend with the administrator username and password entered in step 6.
For a non-interactive or CI installation, keep the password in an environment variable and run:
npm run dev -- install \
--config ./installer.config.yaml \
--admin-password "$TYPO3_ADMIN_PASSWORD" \
--yesAfter building, the same CLI is available through node dist/cli.js or the
typo3-auto-install package binary.
Read the first error in the installer output and fix that problem before trying again. Run the preflight checks if the error mentions Node.js, DDEV, or Docker:
npm run dev -- doctorThe installer creates the target directory and starts DDEV early in the process. A failure after that point can leave a partially configured project and running DDEV containers. The next installation will refuse this non-empty directory, so clean it up before retrying.
First, stop and remove the project's containers. Run this from the generated project directory:
cd ../acme-website
ddev stopFrom another directory, use the DDEV project name instead:
ddev stop <project-name>ddev stop removes the containers but keeps the database and project data. If
you want to discard the failed installation completely, remove DDEV's project
record and database as well:
cd ../acme-website
ddev delete --yes
# or to omit snapshots
ddev delete --omit-snapshot --yesddev delete does not delete the project files. After checking that the
directory is the failed project, delete the target directory, then run the
installer again. The delete command removes the DDEV database, so do not use
it if you need to keep data from a partially completed installation.
npm run dev -- install # interactive install
npm run dev -- install --dry-run # show every file and command first
npm run dev -- doctor # check Node.js, DDEV, and Docker
npm run dev -- status --directory ./my-project
npm run dev -- update --directory ./my-project --dry-rununinstall deliberately removes only paths recorded in
.typo3-auto-install/state.json. It does not delete TYPO3 core, the database,
or DDEV containers. It requires both confirmation and --force because a
managed file can have local edits.
installer.config.yaml has these sections:
project: DDEV name, title, and installation directoryadmin: backend account details, except the passwordddev: PHP version and TYPO3 server typedatabase: the DDEV database connectionsitepackage: Composer vendor and TYPO3 extension keydeveloperStack:bootstrap-package,bootstrap-vite,fluid-styled-content,fluid-styled-content-vite,fluid-styled-content-vite-stylex, orastryxextensions: optional TYPO3 extensions, available with every stackfeatures: TYPO3 Rector and Playwright choices
CLI flags override YAML values. Run npm run dev -- install --help for all
available flags.
The chosen stack controls only stack-specific dependencies and generated assets. Shared TYPO3 setup, the local Composer sitepackage repository, dotenv support, Container, optional extensions, Rector, and Playwright remain available in every variant.
| Component | bootstrap-package |
bootstrap-vite |
fluid-styled-content |
fluid-styled-content-vite |
fluid-styled-content-vite-stylex |
astryx |
|---|---|---|---|---|---|---|
| Interactive label | bootstrap_package |
bootstrap_package + Vite |
fluid-styled-content |
fluid-styled-content + Vite |
fluid-styled-content + Vite + StyleX |
Astryx (Vite + StyleX) |
| Sitepackage | install-src/bootstrap-package/sitepackage |
install-src/bootstrap-vite/sitepackage |
install-src/fluid-styled-content/sitepackage |
install-src/fluid-styled-content-vite/sitepackage |
install-src/fluid-styled-content-vite-stylex/sitepackage |
install-src/astryx/sitepackage |
| Content renderer | Bootstrap Package | Bootstrap Package | Fluid Styled Content | Fluid Styled Content | Fluid Styled Content | TYPO3 Astryx |
| Renderer dependency | bk2k/bootstrap-package in the local sitepackage |
bk2k/bootstrap-package in the local sitepackage |
typo3/cms-fluid-styled-content in the local sitepackage |
typo3/cms-fluid-styled-content in the local sitepackage |
typo3/cms-fluid-styled-content in the local sitepackage |
skom/typo3-astryx in the local sitepackage (FSC removed) |
| Vite Asset Collector | Not installed | Installed | Not installed | Installed | Installed | Installed |
| Vite tooling | Not installed | Vite, TYPO3 plugin, Sass, Bootstrap, Icons, Popper, npm scripts, and vite.config.js |
Not installed | Vite, TYPO3 plugin, sass-embedded, npm scripts, and vite.config.js |
Vite, TYPO3 plugin, StyleX, unplugin, npm scripts, and vite.config.js |
Vite, TYPO3 plugin, StyleX, unplugin, npm scripts, and vite.config.js |
| DDEV Vite sidecar | Not installed | Installed | Not installed | Installed | Installed | Installed |
baschte/content-animations site set |
Bootstrap Package integration | Bootstrap Package integration | Fluid Styled Content integration | Fluid Styled Content integration | Fluid Styled Content integration | Not configured |
Every developer stack owns a self-contained folder in install-src/. The
installer never layers templates, so changing one stack cannot affect another:
install-src/
shared/ .editorconfig, .gitignore, rector.php
<developer-stack>/
sitepackage/ complete sitepackage, rendered to packages/<name>
root/ project-root files (only stacks that need them)
root/ holds vite.config.js for the Vite stacks and, for the StyleX stack,
also verify-stylex-build.mjs. Each stack folder is complete on its own, so a
fix to a file that several Fluid Styled Content stacks have in common has to be
applied in each of those stack folders.
The Bootstrap-only template is rendered to packages/<sitepackage-name> and
its original bbb placeholders are replaced with the requested values: its
Composer package name becomes <vendor>/<sitepackage-name-with-hyphens>, while
the extension key, PHP namespace, site-set name, RTE preset, and every EXT:
path receive the configured vendor and sitepackage name. Its site-set template
also receives selected extension site-set dependencies, just like the Vite
template.
typo3/cms-base-distribution:^14.3 already includes Fluid Styled Content. The
FSC sitepackage retains typo3/cms-fluid-styled-content in its own
composer.json, so requiring the generated local sitepackage explicitly
preserves that dependency without duplicating it at the project root. Bootstrap
Package is likewise declared by each Bootstrap sitepackage. The FSC/Vite stack
has its own sitepackage with a Vite entrypoint, private SCSS,
and private JavaScript sources. Both FSC/Vite stacks use FSC's built-in content
templates and CSS, with a plain HTML page shell and no Bootstrap packages or
CDN assets. They include no custom content-block examples or replacement FSC
templates. The shared page layout registers the entrypoint once through the
Vite Asset Collector, while the FSC-only stack continues to load
its committed static assets. Vite Asset Collector and the DDEV Vite sidecar
are intentionally absent from the non-Vite stacks.
Fluid Styled Content supplies the standard content-element layouts, templates,
and partials. The sitepackage does not override FSC template paths or bundle
replacement content-element templates. Its PageView files provide the page
wrapper, navigation, and content regions around the FSC-rendered content.
FSC's default CSS covers content-element layout, images, tables, and spacing.
It does not provide a full website theme. The project stylesheet starts empty;
add site-specific styles to Resources/Private/Scss/main.scss for FSC/Vite or
Resources/Private/CSS/main.css and the StyleX sources for FSC/Vite/StyleX.
TYPO3 generates FSC's stylesheet from its site settings and wraps it in the
fsc cascade layer. Vite loads project styles afterwards. Keep project rules
outside a cascade layer to override FSC's normal declarations, even with
less-specific selectors, without !important. This works in development and
production. FSC remains outside Vite because its CSS is generated from
TypoScript settings rather than supplied as an importable CSS file.
Vite installation restarts DDEV after adding the sidecar so its hostname and
VITE_SERVER_URI are active before the development server starts.
All selectable TYPO3 extensions are included in the Composer requirement for every stack. Cookie Manager, Blog, and News have stack-neutral site sets; Content Blocks has no automatic site-set dependency; and Content Animations uses the renderer-specific site set shown above. Rector is a separate Composer development dependency, while Playwright is an independent npm/browser setup, so neither choice is tied to a developer stack.
Select fluid-styled-content + Vite + StyleX at the prompt, set
developerStack: fluid-styled-content-vite-stylex in YAML, or pass
--developer-stack fluid-styled-content-vite-stylex to install.
This fifth stack has its own FSC-based sitepackage with StyleX sources. It installs
skom/stylex-connector and Vite Asset Collector in Composer, plus
@stylexjs/stylex, @stylexjs/unplugin, @babel/parser, Vite, the TYPO3 Vite
plugin, and live reload at the project root. DDEV uses Node.js 22. This stack
uses plain CSS and StyleX, so it does not install Sass.
The connector's 1.0.0 tag lacks the maintained manifest adapter and validation
command. The installer therefore pins the root Composer requirement to
dev-main#701d870b9ae55e8c434af24532b95c10f7e54ef2, a published commit containing
both. The sitepackage requires dev-main; the explicit root requirement permits
that development dependency without lowering global Composer stability.
When these changes have a tagged release, replace the pin and branch constraint
in src/stylex.ts with the released minimum version.
The generated project includes:
Configuration/ViteEntrypoints.jsonand one<vite:asset>call in the page layout- an active
skom/stylex-connectorSite Set dependency and manifest registration inext_localconf.php Resources/Private/JavaScript/Stylex/Site.stylex.js, imported byMain.entry.js, withSite.shellandSite.contentclasses used in Fluid- a Vite import of the connector's maintained
Resources/Private/Build/stylex-manifest.mjsadapter after the StyleX transform, with the sitepackage namespace and legacy aliases enabled - development loading and refresh of
/virtual:stylex.cssfrom the Vite origin - page caching disabled only in Development contexts so Fluid follows changing atomic class names
- a
verify-stylex-build.mjsscript that checks emitted assets, Fluid CSS selectors, version 2 manifest output, and paired CSS checksums
FSC supplies its standard CSS for content elements. The shared page layout
adds the StyleX wrapper classes only for the StyleX stack. StyleX uses
useCSSLayers: false to work with that unlayered
CSS. The connector's separate TypoScript CSS include stays disabled because
Vite Asset Collector delivers the built CSS.
The installer adds the DDEV sidecar with npm selected, restarts DDEV, and runs
ddev npm run build, then
ddev typo3 stylex:validate --required-key Site.shell --required-key Site.content,
followed by a TYPO3 cache flush. A failed build, stale or missing CSS, invalid
manifest, unintended key collision, or missing required key stops installation
before success is recorded. Both manifests must
be deployed together:
public/_assets/vite/.vite/manifest.jsonand its referenced assetspackages/<sitepackage>/Resources/Public/StylexManifest/stylex-manifest.json
For development, run ddev vite and open the TYPO3 page. Give each new
*.stylex.js file a unique basename and import it from Main.entry.js.
Use {stylex:class(styles: 'FileName.variant')} in Fluid through the enabled
legacy aliases. The adapter also emits canonical keys containing the sitepackage
namespace, root-relative module path, style object, and variant. If you disable
legacy aliases to allow duplicate basenames, migrate the Fluid keys and required
keys in the verifier and validation commands together. The adapter preserves
StyleX null conflict entries and supports static stylex.create() styles in
JS, JSX, TS, and TSX files. Dynamic style arguments need a project-specific
recipe adapter.
For production, stop the dev server and run ddev npm run build, then
ddev typo3 stylex:validate --required-key Site.shell --required-key Site.content
and ddev typo3 cache:flush. Serve built assets in TYPO3's Production context.
The generated .env defaults to Development, which expects ddev vite to be running. The update command also rebuilds and validates this
stack after dependency updates. The generated verifier and Vite configuration
are tracked in installer state for status and uninstall. The manifest adapter
is owned by the Composer dependency, so the installer does not copy or track it.
Build and validate assets in a staging release and promote CSS, JavaScript, and
both manifests together. CSS artifact paths are relative to the StyleX manifest;
preserve this directory layout during deployment. Atomic JSON writes alone do
not synchronize an independently deployed CSS file.
The sidecar installation follows the official DDEV add-on instructions.
Select Astryx (Vite + StyleX) at the prompt, set developerStack: astryx in YAML, or pass --developer-stack astryx to install.
This stack installs only TYPO3 with Vite, praetorius/vite-asset-collector, skom/stylex-connector, and skom/typo3-astryx, while excluding typo3/cms-fluid-styled-content (removed via composer remove typo3/cms-fluid-styled-content) and excluding bootstrap_package.
It uses the astryx_sitepackage template with StyleX token and component definitions, Vite entrypoints, and progressive enhancement. The generated sitepackage declares a Site Set dependency on skom/typo3-astryx.
install performs these actions in this order. --dry-run completes steps
1 through 6, then stops before it writes files or executes the plan.
- Load
installer.config.yaml, apply CLI flag overrides, and validate the resulting configuration. - Ask for any interactive values, including the administrator password, or
require
--admin-passwordwhen--yesskips prompts. - Check Node.js, DDEV, and Docker. A real installation stops if any check fails.
- Ask for confirmation unless
--yesis set. - Refuse a target directory that already has installer state or is non-empty,
unless
--forceis set. - Build and print the complete installation plan.
- Create the target directory.
- Run
ddev configwith the configured project name, TYPO3 project type,publicdocroot, and PHP version. - Start DDEV.
- Run Composer's
create-projectfortypo3/cms-base-distribution:^14.3. - Run
ddev typo3 setup --forcewith the configured database connection, administrator account, and TYPO3 server type. - Configure Composer to allow the dotenv connector.
- Configure Composer to use the TYPO3 Composer repository.
- Configure Composer to load path repositories from
packages/*. - Configure Composer's platform PHP version as 8.3.0.
- Create
packages/. - Render the sitepackage template into
packages/<sitepackage>, replacing its placeholder names and administrator details. - Require TYPO3 Console, dotenv connector, Container, the selected optional extensions, and the rendered sitepackage. Each Vite stack also requires Vite Asset Collector; Bootstrap Package and Fluid Styled Content are declared by their respective sitepackages.
- Update Composer dependencies with their dependencies.
- Apply TYPO3 database schema updates.
- Flush the TYPO3 cache.
- For each Vite stack, initialize npm, install Vite and its TYPO3 plugin,
add the
dev,build, andwatchscripts, and copyvite.config.js. The Bootstrap/Vite stack also installs Bootstrap, Bootstrap Icons, Popper, and Sass; the FSC/Vite stack installssass-embeddedfor SCSS builds. - Copy
.editorconfigand.gitignore. - Write
.envwith the configured database settings and development values. - Write the generated project README.
- For each Vite stack, install the DDEV Vite sidecar. The StyleX stack initializes its npm tooling after writing the shared project files, then restarts DDEV, builds and validates both manifests and CSS, and flushes caches.
- If Rector is enabled, install TYPO3 Rector and copy
rector.php. - If Playwright is enabled, install its npm package and browsers with their system dependencies.
- Warm the TYPO3 cache.
- As the final installation command, run
ddev typo3 extension:setupto activate and initialize installed extensions for either developer stack. - Write
.typo3-auto-install/state.json, which records the installer version, project metadata, and managed paths.
Before the installer copies, renders, or writes over an existing destination,
it saves that destination under .typo3-auto-install/backups/.
The project gets a DDEV TYPO3 v14.3 installation plus:
- a generated copy of the selected sitepackage template under
packages/ - shared TYPO3 tooling:
b13/container,helhum/typo3-console, andhelhum/dotenv-connector - Bootstrap Package with static sitepackage assets, Bootstrap Package with Vite Asset Collector, Vite, and its DDEV sidecar, Fluid Styled Content with static assets, Fluid Styled Content with its Vite-built SCSS and JavaScript, or Fluid Styled Content with Vite-built StyleX CSS and a registered class manifest
- an environment file, project README, editor settings, optional selected TYPO3 extensions, and optional Rector, Playwright tooling
The installer builds its complete plan before it makes changes. --dry-run
prints the plan and redacts administrator and database passwords. When
--force permits an overwrite, it copies the previous installer-managed file
to .typo3-auto-install/backups/ first.
npm run build
npm run test:run
npm run checkThe core is split by responsibility:
src/config/ YAML loading and Zod validation
src/prompts.ts interactive input only
src/installer/ plan construction and execution
src/filesystem.ts native Node filesystem operations
src/process.ts safe, argument-based process execution with Execa
src/preflight.ts environment checks
Installer behavior is covered by the Vitest suite in test/.