Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ LaunchPad is the official Strapi demo app.
- `astro/`: Astro frontend, same content and routes.
- `nuxt/`: Nuxt 4 frontend, same content and routes.
- `tanstack/`: TanStack Start frontend, same content and routes.
- `cli/`: `create-strapi-launchpad`, the npm package that scaffolds this repo. Uses npm, not yarn, since it is published separately.
- Root: setup/dev/format scripts using Yarn 4.5.0. Each directory keeps its own lockfile; this is not a Yarn workspace.

## First Read
Expand Down Expand Up @@ -38,6 +39,7 @@ Run commands from the correct directory.
- Strapi dev: `cd strapi && yarn develop`
- Strapi build: `cd strapi && yarn build`
- A frontend directly: `cd <framework> && yarn dev`
- CLI tests: `yarn test:cli` (verifies the CLI's frontend list still matches this repo)

## Setup

Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ Strap yourself in! You can get started with this project on your local machine b
> npm install -g yarn
> ```

## Quickest start

```bash
npx create-strapi-launchpad my-app
```

It asks which frontend you want, then clones, installs, seeds and starts it.
Pass `--framework astro` (or `nuxt`, `tanstack`, `next`) to skip the question.
The CLI lives in [`cli/`](cli/).

To set the project up by hand instead, carry on below.

## 1. Clone and Install

To infinity and beyond! Clone the repo and install root dependencies:
Expand Down
5 changes: 5 additions & 0 deletions cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
*.log

# scratch output from manual CLI runs
/tmp-*/
21 changes: 21 additions & 0 deletions cli/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Paul Bratslavsky

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
82 changes: 82 additions & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# create-strapi-launchpad

Scaffold [LaunchPad](https://github.com/strapi/LaunchPad), Strapi's official
demo application, with the frontend you want to work in.

```bash
npx create-strapi-launchpad my-app
```

That clones LaunchPad, installs it, seeds the demo content, and starts the
dev servers. With no `--framework` it asks which frontend to run.

## Frontends

LaunchPad ships four frontends against one Strapi backend.

| Frontend | Flag | Port |
| -------------- | ---------------------------- | ---- |
| Next.js | `--framework next` (default) | 3000 |
| Nuxt 4 | `--framework nuxt` | 3001 |
| TanStack Start | `--framework tanstack` | 3002 |
| Astro | `--framework astro` | 4321 |

Strapi runs on **1337** for all of them.

```bash
npx create-strapi-launchpad my-app --framework astro
```

## Options

| Option | Description |
| ------------------------ | ---------------------------------------------------- |
| `-f, --framework <name>` | Frontend to run. Prompts if omitted. |
| `-r, --ref <ref>` | Branch or tag of the LaunchPad repo to clone. |
| `--no-seed` | Skip seeding the demo content. |
| `--no-start` | Set everything up, but do not start the dev servers. |
| `--no-git` | Do not initialize a git repository. |
| `--dry-run` | Print what would happen and exit. |

## Requirements

- Node.js 20.19 or newer
- Git

Yarn is required. Every LaunchPad directory ships a `yarn.lock` and its
scripts call yarn directly, so that is what the CLI drives. If yarn is
missing, the CLI enables it through Corepack for you.

## What it does

1. Clones LaunchPad (shallow) and removes its history
2. Initializes a fresh git repository with one commit
3. `yarn install && yarn setup` — installs every workspace and writes `.env` files
4. `yarn seed` — imports the demo content into SQLite
5. `yarn dev` (or `dev:astro`, `dev:nuxt`, `dev:tanstack`)

Use `--dry-run` to see the plan for any combination of flags without touching
the disk.

## Development

```bash
npm install
npm test
node ./bin/cli.js my-app --dry-run
```

Frontends are declared in one place, [`src/frameworks.js`](src/frameworks.js).

It has to be a separate copy, because the CLI runs before the repo is cloned.
That copy can drift, and when it does the CLI checks the wrong port or calls a
dev script that does not exist. `test/registry-matches-launchpad.test.js`
reads the real sources — `../scripts/frontends.mts`, the root `package.json`
scripts and the frontend directories — and fails if they disagree.

That test is why this package lives in the LaunchPad repo rather than its own.
Run it from the repo root with `yarn test:cli`.

## License

MIT
60 changes: 60 additions & 0 deletions cli/bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env node
import { program } from 'commander';
import { createRequire } from 'node:module';

import { createLaunchpadApp } from '../src/commands/create.js';
import { FRAMEWORKS, frameworkNames } from '../src/frameworks.js';

// Read the version from package.json rather than repeating it here, so the
// two cannot drift.
const require = createRequire(import.meta.url);
const { version } = require('../package.json');

const frameworkList = FRAMEWORKS.map(
(f) => ` ${f.name.padEnd(9)} ${f.label} (port ${f.port})`
).join('\n');

program
.name('create-strapi-launchpad')
.description('Scaffold the official Strapi LaunchPad demo application')
.version(version)
.argument('[directory]', 'directory to create the project in', 'launchpad')
.option(
'-f, --framework <name>',
`frontend to run (${frameworkNames().join(', ')}) — prompts if omitted`
)
.option('-r, --ref <ref>', 'branch or tag of the LaunchPad repo to clone')
.option(
'--repo <url|path>',
'clone from somewhere else — a fork, or a local checkout for testing'
)
.option('--no-seed', 'skip seeding demo data')
.option('--no-start', 'skip starting dev servers after setup')
.option('--no-git', 'skip initializing a git repository')
.option('--dry-run', 'print what would happen without doing it')
.addHelpText(
'after',
`
Frontends:
${frameworkList}

Examples:
$ create-strapi-launchpad my-app
$ create-strapi-launchpad my-app --framework astro
$ create-strapi-launchpad my-app --framework nuxt --no-start
$ create-strapi-launchpad my-app --dry-run
$ create-strapi-launchpad my-app --repo ../LaunchPad --framework nuxt

All frontends share one Strapi backend on port ${1337}.
`
)
.action(async (directory, options) => {
try {
await createLaunchpadApp(directory, options);
} catch (error) {
console.error(error?.message ?? error);
process.exit(1);
}
});

program.parse();
Loading