Create a project
The create-pluto command makes a new project from a template, installs the dependencies, and tells you how to start it.
Run the CLI
npm create pluto@latest
pnpm create pluto@latest
yarn create pluto
bun create pluto@latest
deno run -A npm:create-pluto@latest
The wizard
The wizard asks these things, in this order:
- Project directory. The default is
my-pluto-project. The CLI makes the directory if it does not exist. - Website title. The default is
My Awesome Website. - Backend. Choose
Git CMS (Markdown files in Git)orSupabase. With the Git CMS, the CLI also makes the project a Git repository: in development, each save in the admin is a commit in it. - Supabase values. Only for Supabase. See With Supabase.
- Template. The list shows only the templates that the backend allows.
- Layers. Only for
Dashboard only. See Dashboard only. - Package manager.
npm,pnpm,yarn,bunordeno. The default is the one that runs the CLI.
| Backend | Templates |
|---|---|
| Supabase | Shop, Blog, Dashboard only |
| Git CMS (Markdown files in Git) | Blog, Dashboard only |
If the backend has only one template, the wizard picks it for you.
Dashboard only
This template has no public site. It is Pluto with the admin at /admin and the public API: a headless CMS to deploy, for a site in any stack. The home page redirects to /admin. See Use Pluto headless.
It works with both backends. The CLI sets the backend in it. With Supabase, the layer in nuxt.config.ts becomes @plutocms/supabase. Then the wizard asks which layers to add. You can select several:
| Backend | Layers |
|---|---|
| Supabase | Shop, Blog, 3D |
| Git CMS (Markdown files in Git) | 3D |
The CLI adds each layer to extends in nuxt.config.ts and to package.json. Shop and Blog extend @plutocms/supabase themselves, so the app extends them in place of @plutocms/supabase. See Layers.
The blog is one template for both backends. The pages are the same. The CLI sets the backend in it: the layer in nuxt.config.ts (@plutocms/core or @plutocms/supabase-blog), the packages, the sample posts in content/ (Git CMS only), and the .env.
Then the CLI downloads the template, writes .env, and installs the dependencies. At the end, it shows the next steps:
◇ Next steps
│ cd my-pluto-project
│ npm run dev
│
│ Then open /admin on the dev server.
│
│ Local Git publishing works in development only. To publish from a
│ deployed site, connect GitHub (Settings > GitHub).
└ Docs: https://pluto.vulmix.dev/docs/getting-started/create-a-project
The note about local Git shows only for the Git CMS. The dev command follows the package manager: pnpm run dev, bun run dev, deno task dev, and so on.
Before the download, the wizard checks two things. If nuxt.config.ts exists in the current directory, the wizard asks "Nuxt project detected. Do you want to add Pluto environment variables?". If the target directory is not empty, the wizard asks for confirmation.
You can cancel at any prompt.
Skip the prompts
| Option | What it does |
|---|---|
<folder> (first argument) | The project directory. |
-t, --template | blog, shop or admin (Dashboard only). It skips the template prompt. |
--backend | git (the Git CMS) or supabase. It skips the backend prompt. |
--layers | The layers to add to the admin template, separated by commas: shop, blog, 3d. none adds no layers. It skips the layers prompt. |
--pm, --package-manager | The package manager. It skips that prompt. |
--no-install | Do not install the dependencies. The next steps then show the install command. |
npm create pluto@latest my-blog -t blog --backend git --pm pnpm
npm create pluto@latest my-cms -t admin --backend supabase --layers shop,3d
The shop works with Supabase only, so -t shop needs no --backend. The blog asks for the backend when --backend is not set. A template with a backend that it does not support (-t shop --backend git), an unknown name, or an unknown package manager stops the CLI: it prints the right names and exits with status 1.
The older shortcuts still work: core-blog is -t blog --backend git, supabase-blog is -t blog --backend supabase, and supabase-shop is -t shop.
In a script (no terminal), the CLI does not ask for the website title, the layers or the package manager. It uses the defaults, and adds no layers. So create-pluto my-blog -t blog --backend git --pm bun runs with no question.
What the CLI writes
The CLI downloads the template from GitHub with giget:
gh:plutocms/pluto-blog-template # the blog, both backends
gh:plutocms/pluto-supabase-shop-template # the shop
gh:plutocms/pluto-admin-template # Dashboard only, both backends
Then it writes a .env file. If .env exists, the CLI merges the new values into it. Each value is quoted.
The CLI always writes the website title:
NUXT_PUBLIC_WEBSITE_NAMEfor the blog and the dashboard (both backends).WEBSITE_NAMEfor the shop.
With Supabase
The CLI asks for three values. It checks each one.
| Prompt | Variable |
|---|---|
| Supabase URL | SUPABASE_URL |
| Supabase key | SUPABASE_KEY |
Database connection string (postgres:// or postgresql://) | DATABASE_URL |
You need a Supabase project first. You can make one at database.new. Find the connection string in the Supabase dashboard: Project Settings, Database, Connection string. The pooler connection string also works.
With the Git CMS
The CLI asks nothing about GitHub. It writes NUXT_PLUTO_GITHUB_SESSION_PASSWORD, a random value with 43 characters.
You make the GitHub App later, from the admin of your site:
- On your machine, you need no App. The dev server signs you in as a local user and edits the files in
content/. - After a deploy, open
/admin/loginand select Create the GitHub App. See Git CMS in 10 minutes.
Start the dev server
Run the commands of the next steps. Then open http://localhost:3000/admin.
With the Git CMS, the dev server reads and writes the local content/ folder. On your machine, you are signed in as a local user. See Git CMS.
plutoLayer helper and PLUTO_LOCAL_ROOT are for people who work on Pluto itself. See Local layers.