@raulmoracode/create
v1.1.1
Published
Professional CLI to scaffold React + Vite and Next.js projects with Tailwind CSS, shadcn, Biome and Vitest.
Maintainers
Readme
@raulmoracode/create
Professional CLI to scaffold modern React projects. Built with Node.js, TypeScript, Clack and pnpm.
- Package:
@raulmoracode/create(published to npmjs) - Repository:
raulmoracode/raulmoracode-create - Command:
raulmoracode-create
Requirements
- Node.js 24 LTS
- pnpm 12 (declared per project via
packageManager). The CLI aborts early if another major is active; fix it withcorepack enable && corepack prepare [email protected] --activate(ornpm install -g [email protected]) - npm
- Git with a configured identity (
user.nameanduser.email) - A GitHub account and an existing empty repository for the new project
- VS Code (optional, used to open the project at the end)
Install globally
The package is published to npmjs. No authentication needed.
npm install -g @raulmoracode/createVerify:
raulmoracode-createUsage
raulmoracode-createThe CLI guides you through the whole process with Clack prompts:
- Select the technology: React + Vite or Next.js.
- Select the technologies to include (everything preselected by default).
- Enter the project name.
- Enter the GitHub repository URL (the repository must already exist).
- The project is created with the official generators (
create-vite/create-next-app) and fully configured. - Git is initialized, the remote is configured, the initial commit is created and pushed to GitHub.
- Optionally open the project with VS Code.
Available flags:
raulmoracode-create --verbose # print the output of every external command
raulmoracode-create --help # show help
raulmoracode-create --version # show the installed versionUpgrading an existing project
Projects generated by 1.0.8 or later ship a raulmoracode.json manifest, so later CLI improvements can be applied to them. Run this inside the project:
pnpm dlx @raulmoracode/create@latest upgradeIt re-applies the managed configuration (tooling, hooks, CI, workspace, pinned dependencies), runs any migration published in between, and opens a ready-for-review pull request describing every change, which you merge yourself. It never touches your application code, README.md, CHANGELOG.md or LICENSE, and it never rewrites history.
Requirements: Node 24, pnpm 12, a clean working tree, a GitHub remote and the GitHub CLI (gh auth login).
What the CLI does
Scaffolds with the official generators (never a hand-written template):
- React + Vite:
pnpm create [email protected] <name> --template react-ts(thecreate-viterelease line that scaffolds the Vite 8.x line;[email protected]does not exist), then pins[email protected],[email protected]and[email protected]. - Next.js:
pnpm create [email protected] <name> --ts --app --src-dir --import-alias "@/*" --biome --use-pnpm --disable-git --yes.
- React + Vite:
Installs dependencies with pnpm and pins exact versions (no
^or~).Configures Tailwind CSS 4.3.3 (CSS-first configuration,
@tailwindcss/vitefor Vite and@tailwindcss/postcssfor Next.js).Prepares shadcn: writes a complete
components.json(including the@raulmoracoderegistry), thecn()helper (src/lib/utils.ts) and the registry path aliases (@components/*,@lib/*,@hooks/*in the tsconfigs) sopnpm dlx [email protected] add @raulmoracode/<component>resolves file targets out of the box. No components are preinstalled; add them later withpnpm dlx [email protected] add <component>.Optionally applies the Raulmoracode nature theme from the registry (
@raulmoracode/theme, no version pin — registry item, not an npm package — applied viapnpm dlx [email protected] add @raulmoracode/theme --yes --overwrite, requires shadcn): nature tokens land in the Tailwind entry CSS,[email protected]is pinned, and the CLI removes the Next-oriented leftovers the shadcn CLI drops intosrc/on Vite projects.Installs Zustand 5.0.15, React Hook Form 7.89.0, Zod 4.6.5 and TanStack Query 5.104.0, and wires the TanStack Query provider.
Configures Biome 2.5.14 (formatter, linter and organize imports) and removes the ESLint/Oxlint leftovers from the official templates.
Configures Vitest 5.0.2, @testing-library/react 16.3.3 and @testing-library/dom 10.4.2 (plus
jsdom, required by Testing Library, andclsx+tailwind-merge, required by the shadcncn()helper).Configures VS Code (
.vscode/settings.jsonand.vscode/extensions.json).Pins Node.js 24 via
.nvmrcand writes.editorconfig.Writes the MIT
LICENSEwith the project author and the current year, and setslicense: "MIT"inpackage.json, so the project is publishable as it comes out.Applies branding: removes the template's own
<title>and favicon link and injects nothing in their place, so the tab title, favicon and social tags come fromsrc/config/site.ts(see below) instead of being hardcoded inindex.htmlfor Vite or in the root layout metadata for Next.js.Ships a minimal starter for React + Vite:
public/andsrc/assets/are emptied,App.tsxrenders a simple hello andApp.cssstarts empty.Ships a minimal starter for Next.js:
public/is emptied andpage.tsxrenders a simple hello (its orphanedpage.module.cssis removed).AGENTS.mdis kept andCLAUDE.mdis removed. Addssrc/app/error.tsxandsrc/app/not-found.tsx, which are Next.js file conventions, so they need no wiring. They deliberately use only Tailwind utilities that exist everywhere instead of theme tokens, so the registry theme cannot leave them unstyled.Fills in project metadata in
package.json:author(Raul Mora, https://raulmoracode.com),homepageandrepositorywith the GitHub URL you enter at the start.Writes a project
README.md(overwriting the scaffolder default): title with the project name, requirements, a scripts table matching the finalpackage.json, the selected tech stack with exact versions, the shadcn registry workflow (only with shadcn), Git workflow (only with Husky) and a per-framework structure overview.Writes
pnpm-workspace.yamlwithminimumReleaseAge: 10080plusminimumReleaseAgeExcludeentries for every locked package, so installs keep working (pnpm enforces the policy against the whole lockfile, not just direct dependencies). When shadcn is selected, the@raulmoracode/*scope is also excluded soshadcn add @raulmoracode/<component>can install freshly published packages from your registry.Writes
src/config/site.ts, the single place a project declares how it presents itself: tab title, description, favicon, social preview image and alt text, author, X handle, locale and theme color. Both frameworks read it, so nothing has to be repeated per framework:- React + Vite: a small
siteHead()plugin invite.config.tsinjects the tags intoindex.htmlthroughtransformIndexHtml, at dev and build time. The template's own<title>and favicon link are removed, so there is exactly one of each. - Next.js: the
metadataexport insrc/app/layout.tsxis built fromsite, and Next resolves thetwitterandopenGraphfields natively.
faviconandsocialImageaccept either a full URL or a local path served frompublic/(/favicon.svg,/imagen.png). The CLI does not generate any image: you provide it. Local paths are emitted as they are, and onceurlis set they are resolved against it, because social crawlers cannot resolve relative URLs. The result is a proper preview when a link is shared on X, WhatsApp, Slack or LinkedIn, and changing the title, description or favicon later is a one-file edit. Defaults come from the project name and the real pinned stack read frompackage.json;descriptionis empty on purpose and empty values are never rendered, so the HTML never carries a blank meta tag.- React + Vite: a small
Initializes Git on
main, adds the remote, creates the commitchore: initial project setupand pushes withgit push -u origin main(never--force). If the remote already contains commits that do not exist locally, the process stops with a clear message instead of overwriting anything.
Generated projects
Every generated project includes:
- React + Vite or Next.js (official structure)
- Tailwind CSS 4
- shadcn ready (
components.jsonwith the@raulmoracoderegistry and thecn()helper) - Raulmoracode nature theme (optional,
@raulmoracode/themevia[email protected]; pins[email protected]) - Zustand
- React Hook Form + Zod
- TanStack Query (provider included)
- Biome (format, lint, organize imports)
- Vitest + Testing Library
- VS Code settings
- Husky + Commitlint (
.husky/pre-commitand.husky/commit-msg, both executable, pluscommitlint.config.ts) - Continuous integration (
.github/workflows/ci.yml) - Branding driven by
src/config/site.ts(tab title, favicon and social preview) README.md(overview, scripts, tech stack, registry workflow)CHANGELOG.md(Keep a Changelog)- MIT
LICENSE pnpm-workspace.yamlwithminimumReleaseAge: 10080raulmoracode.json: the CLI version, framework, selected tech, project identity and a hash per managed file, soraulmoracode-create upgradecan tell your edits from the CLI's- Node.js 24 (
.nvmrc) and.editorconfig - pnpm (
pnpm-lock.yaml, nopackage-lock.jsonoryarn.lock) - Next.js error pages (
src/app/error.tsxandsrc/app/not-found.tsx), which are file conventions and need no wiring - Git initialized and pushed to GitHub
Commands in a generated project
pnpm install
pnpm dev
pnpm build
pnpm test
pnpm check
pnpm format
pnpm lintAdd shadcn components:
pnpm dlx [email protected] add card
pnpm dlx [email protected] add @raulmoracode/<component>After adding components, normalize their style with Biome (the shadcn CLI uses its own formatting):
pnpm exec biome check --write .Vite projects resolve the @/* alias to src/* (tsconfig.app.json, root tsconfig.json and vite.config.ts). Both frameworks also map the @raulmoracode registry aliases (@components/*, @lib/*, @hooks/* to src/...) so registry file targets resolve when running pnpm dlx [email protected] add @raulmoracode/<component>.
Every generated project ships an AGENTS.md file with guidelines for AI coding agents (source of truth, conventions, validation, Git safety and security rules), plus a project tooling section (pnpm exclusively, script map and the shadcn workflow).
GitHub authentication
The CLI runs git push -u origin main, so Git must be authenticated against GitHub. Any of these work:
- GitHub CLI:
gh auth login - A credential manager / SSH key configured for
github.com
npm
Install
npm install -g @raulmoracode/createUpdate the global installation
npm install -g @raulmoracode/createPublish (maintainers)
pnpm install
pnpm build
pnpm test
npm publish --access publicCreate the NPM_TOKEN (granular, read+write on @raulmoracode/create) at npmjs.com > Access Tokens and save it as Settings > Secrets > Actions > NPM_TOKEN.
The repository also ships a GitHub Actions workflow (.github/workflows/publish.yml) that builds, runs the offline tests and publishes the package to npmjs on every v* tag using NPM_TOKEN, plus a CI workflow (.github/workflows/ci.yml) that runs check, lint, offline tests and build on every main push and pull request, with each framework E2E (e2e-vite, e2e-next) as a separate job. A third workflow (.github/workflows/e2e-scheduled.yml) runs both framework E2Es every Monday at 06:00 UTC (and on demand with gh workflow run e2e-scheduled.yml) to detect breakage outside the pinned versions (transitive dependencies, the shadcn registry, GitHub/npm). It only observes: it never updates anything. Failed runs notify by email, and GitHub disables scheduled workflows after 60 days without repository activity.
Development
pnpm install
pnpm build
pnpm testPlain pnpm test skips the network E2E. To run one framework's E2E (Node 24 and network required):
E2E_FRAMEWORK=vite pnpm test --run tests/e2e.test.ts tests/upgrade-e2e.test.ts
E2E_FRAMEWORK=next pnpm test --run tests/e2e.test.ts tests/upgrade-e2e.test.tsOther useful scripts:
pnpm check # biome check .
pnpm format # biome format --write .
pnpm lint # biome lint .Architecture
src/
├── index.ts # entry point (shebang)
├── cli/ # orchestration and Clack output
├── prompts/ # user interaction (Clack)
├── generators/ # project configuration steps
├── frameworks/ # vite / next specific logic
├── git/ # git command builders and wrappers
├── config/ # configuration file templates
└── utils/ # exec, filesystem, validation
tests/ # vitest suite (external commands are mocked)External commands are always executed with argument arrays through utils/exec.ts (never string interpolation), and every user input is validated before use.
Verified adjustments
The following deviations from the naive expected configuration were verified against the real tools and are intentional:
[email protected]is used for Vite projects because[email protected]does not exist; the 9.x line is the one that scaffolds the Vite 8.x line.viteis then pinned to8.3.1exactly.components.jsonmust contain the full shadcn configuration ($schema,style,tailwind,rsc,tsx,aliases) because shadcn 4.x rejects a config with onlyregistries— andpnpm dlx [email protected] add cardis a hard requirement. The@raulmoracoderegistry entry is exactly the mandated one.biome.jsonenables organize imports throughassist.actions.source.organizeImportsbecause Biome 2.5.14 removed the top-levelorganizeImportskey; it ignoresdist/.nextbuild output; and disablesnoSvgWithoutTitle/noAmbiguousAnchorText, which fire on the official Vite/Next template demo assets.jsdom(Testing Library DOM environment) andclsx+tailwind-merge(shadcncn()helper) are installed because they are strictly required by the mandated Testing Library and shadcn setups.
Packaging and local verification
pnpm build
npm pack
npm install -g ./raulmoracode-create-*.tgz
raulmoracode-createThe glob keeps working across versions: npm pack names the tarball after the current package.json version, so a hardcoded name would go stale on every release.
The packaged tarball contains dist/ (including the raulmoracode-create bin with its shebang), README.md and LICENSE.
