Skip to content

Add smart init flow for existing projects#17

Open
AmanVarshney01 wants to merge 11 commits intomainfrom
aman/add-smart-init-flow
Open

Add smart init flow for existing projects#17
AmanVarshney01 wants to merge 11 commits intomainfrom
aman/add-smart-init-flow

Conversation

@AmanVarshney01
Copy link
Member

@AmanVarshney01 AmanVarshney01 commented Mar 10, 2026

Summary

  • make the default CLI route to init when package.json exists and --name/--template are not provided
  • keep create as the explicit new-project scaffold flow
  • reuse framework-specific Prisma file layouts for Next, SvelteKit, Astro, Nuxt, TanStack Start, and Hono
  • skip overwriting existing Prisma files during init and document the new behavior

Summary by CodeRabbit

Release Notes

  • New Features

    • Added smart initialization flow that detects whether to initialize Prisma in existing projects or scaffold new ones.
    • New explicit create-prisma create command for non-interactive project creation.
    • TanStack Start template now available.
    • Generates migration and seeding configuration automatically.
    • Auto-detects package manager and configures Prisma instance location.
  • Documentation

    • Updated README with detailed guidance on initialization, scaffolding, and database provisioning workflows.

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR adds a new initialization workflow that enables Prisma setup in existing projects. It introduces an init command that is intelligently invoked from the create command when a package.json exists, alongside new init templates, template rendering, and infrastructure updates to support singleton path configuration.

Changes

Cohort / File(s) Summary
Init Command Flow
src/commands/init.ts, src/commands/create.ts
New init.ts implements complete Prisma initialization workflow with early-exit path in create.ts when shouldInitCurrentProject resolves true. Creates TanStack Start template option and accepts allowInitCurrentProject flag.
Init Templates
templates/init/prisma-instance.ts.hbs, templates/init/prisma.config.ts, templates/init/prisma/schema.prisma.hbs, templates/init/prisma/seed.ts.hbs
Four new template files for Prisma configuration, schema, seeding, and client instantiation with conditional provider-specific logic (Pg, MariaDB, BetterSQLite3, MSSQL).
Setup Infrastructure
src/tasks/setup-prisma.ts, src/templates/render-init-template.ts, src/types.ts
Extends setup-prisma with singletonPath mechanism and promptForPackageManager option. New render-init-template.ts orchestrates init template scaffolding. Types updated with tanstack-start and singletonPath properties.
CLI Integration
src/index.ts, src/constants/dependencies.ts, src/tasks/install.ts
New usesExplicitCreateSubcommand helper controls init triggering. Adds tsx to dependency map and Prisma devDependencies.
Documentation
README.md
Updated usage guide explaining new init flow, smart create behavior, template options, and generated artifacts including db:seed and migrations.seed hooks.

Possibly related PRs

  • prisma/create-prisma#11 — Directly modifies the create/init flow and overlapping infrastructure files with an alternate approach.
  • prisma/create-prisma#12 — Modifies Prisma scaffolding and client-singleton logic relevant to template rendering and setup-prisma updates.

Suggested reviewers

  • mhartington
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Add smart init flow for existing projects' directly and clearly describes the main change: introducing a smart initialization flow for Prisma in existing projects rather than requiring explicit scaffolding.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aman/add-smart-init-flow

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tasks/setup-prisma.ts (1)

57-67: 🧹 Nitpick | 🔵 Trivial

Centralize the singleton path rules.

Lines 57-67 and 452-460 now encode the same framework lookup order in two places. That list is already on different relative bases (packages/db/src/client.ts vs src/client.ts under prismaProjectDir), so the next template addition can easily update validation without updating resolution, or vice versa.

♻️ Suggested consolidation
+const prismaSingletonCandidates = [
+  "src/lib/prisma.ts",
+  "src/lib/prisma.server.ts",
+  "src/lib/server/prisma.ts",
+  "server/utils/prisma.ts",
+] as const;
+
+async function findFirstExistingPath(
+  baseDir: string,
+  candidates: readonly string[]
+): Promise<string | undefined> {
+  for (const relativePath of candidates) {
+    const absolutePath = path.join(baseDir, relativePath);
+    if (await fs.pathExists(absolutePath)) {
+      return absolutePath;
+    }
+  }
+}
+
 const requiredPrismaFileGroups = [
   ["prisma/schema.prisma", "packages/db/prisma/schema.prisma"],
   ["prisma/seed.ts", "packages/db/prisma/seed.ts"],
   ["prisma.config.ts", "packages/db/prisma.config.ts"],
   [
-    "src/lib/prisma.ts",
-    "src/lib/prisma.server.ts",
-    "src/lib/server/prisma.ts",
-    "server/utils/prisma.ts",
+    ...prismaSingletonCandidates,
     "packages/db/src/client.ts",
   ],
 ] as const;
...
-  const singletonPath = (await fs.pathExists(path.join(prismaProjectDir, "src/lib/prisma.ts")))
-    ? path.join(prismaProjectDir, "src/lib/prisma.ts")
-    : (await fs.pathExists(path.join(prismaProjectDir, "src/lib/prisma.server.ts")))
-      ? path.join(prismaProjectDir, "src/lib/prisma.server.ts")
-    : (await fs.pathExists(path.join(prismaProjectDir, "src/lib/server/prisma.ts")))
-      ? path.join(prismaProjectDir, "src/lib/server/prisma.ts")
-      : (await fs.pathExists(path.join(prismaProjectDir, "server/utils/prisma.ts")))
-        ? path.join(prismaProjectDir, "server/utils/prisma.ts")
-        : path.join(prismaProjectDir, "src/client.ts");
+  const singletonPath =
+    (await findFirstExistingPath(prismaProjectDir, [
+      ...prismaSingletonCandidates,
+      "src/client.ts",
+    ])) ?? path.join(prismaProjectDir, "src/client.ts");

Also applies to: 452-460


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 74dafb57-2ebb-46bf-ac8d-c3beec11fbf1

📥 Commits

Reviewing files that changed from the base of the PR and between 08e6bb6 and a8bfb6a.

📒 Files selected for processing (24)
  • README.md
  • src/cli.ts
  • src/commands/create.ts
  • src/commands/init.ts
  • src/index.ts
  • src/tasks/setup-prisma.ts
  • src/templates/render-init-template.ts
  • src/types.ts
  • templates/create/tanstack-start/.gitignore
  • templates/create/tanstack-start/.yarnrc.yml.hbs
  • templates/create/tanstack-start/README.md.hbs
  • templates/create/tanstack-start/deno.json.hbs
  • templates/create/tanstack-start/package.json.hbs
  • templates/create/tanstack-start/prisma.config.ts
  • templates/create/tanstack-start/prisma/schema.prisma.hbs
  • templates/create/tanstack-start/prisma/seed.ts.hbs
  • templates/create/tanstack-start/src/lib/prisma.server.ts.hbs
  • templates/create/tanstack-start/src/routeTree.gen.ts
  • templates/create/tanstack-start/src/router.tsx
  • templates/create/tanstack-start/src/routes/__root.tsx.hbs
  • templates/create/tanstack-start/src/routes/index.tsx.hbs
  • templates/create/tanstack-start/src/styles.css
  • templates/create/tanstack-start/tsconfig.json
  • templates/create/tanstack-start/vite.config.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/commands/create.ts (1)

167-174: ⚠️ Potential issue | 🟠 Major

Only enable smart-init for the default entrypoint.

Lines 167-174 apply the init heuristic inside runCreateCommand() itself, so the explicit create-prisma create path will still switch into init whenever the current directory has a package.json. That breaks the “create is the explicit scaffold flow” contract, and create-only flags like --force / --skills can get dropped once control moves to runInitCommand().

💡 Suggested direction
-export async function runCreateCommand(rawInput: CreateCommandInput = {}): Promise<void> {
+export async function runCreateCommand(
+  rawInput: CreateCommandInput = {},
+  options: { allowSmartInit?: boolean } = {}
+): Promise<void> {
   try {
     const input = CreateCommandInputSchema.parse(rawInput);

-    if (await shouldInitCurrentProject(input)) {
+    if (options.allowSmartInit && (await shouldInitCurrentProject(input))) {
       await runInitCommand(input);
       return;
     }

Then only the root/no-subcommand handler should pass allowSmartInit: true.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cf135701-182f-46f6-b585-329832514498

📥 Commits

Reviewing files that changed from the base of the PR and between a8bfb6a and 3f248a2.

📒 Files selected for processing (5)
  • README.md
  • src/commands/create.ts
  • src/commands/init.ts
  • src/templates/render-init-template.ts
  • src/types.ts

@AmanVarshney01 AmanVarshney01 force-pushed the aman/add-smart-init-flow branch from 3f248a2 to 00ab047 Compare March 10, 2026 15:32
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/tasks/setup-prisma.ts (1)

419-475: ⚠️ Potential issue | 🟠 Major

Validate required Prisma files against prismaProjectDir, not projectDir.

Line 464 checks the required-file groups under projectDir, but Lines 465-475 resolve the singleton under prismaProjectDir. In a monorepo those bases can differ, which means this can reject a valid packages/db/src/client.ts when the command runs inside packages/db, or accept an unrelated root-level src/lib/prisma.ts and then return a missing packages/db/src/client.ts. The validator and resolver need to use the same base directory and the same candidate set.

Suggested direction
-const requiredPrismaFileGroups = [
-  ["prisma/schema.prisma", "packages/db/prisma/schema.prisma"],
-  ["prisma/seed.ts", "packages/db/prisma/seed.ts"],
-  ["prisma.config.ts", "packages/db/prisma.config.ts"],
+const requiredPrismaFileGroups = [
+  ["prisma/schema.prisma"],
+  ["prisma/seed.ts"],
+  ["prisma.config.ts"],
   [
     "src/lib/prisma.ts",
     "src/lib/prisma.server.ts",
     "src/lib/server/prisma.ts",
     "server/utils/prisma.ts",
-    "packages/db/src/client.ts",
+    "src/client.ts",
   ],
 ] as const;

-async function ensureRequiredPrismaFiles(
-  projectDir: string,
+async function ensureRequiredPrismaFiles(
+  prismaProjectDir: string,
   singletonPath?: string
 ): Promise<void> {
  ...
-      const absolutePath = path.join(projectDir, relativePath);
+      const absolutePath = path.join(prismaProjectDir, relativePath);
  ...
}

-  await ensureRequiredPrismaFiles(projectDir, options.singletonPath);
+  const normalizedSingletonPath = options.singletonPath
+    ? path.relative(prismaProjectDir, path.join(projectDir, options.singletonPath))
+    : undefined;
+  await ensureRequiredPrismaFiles(prismaProjectDir, normalizedSingletonPath);
♻️ Duplicate comments (1)
src/commands/init.ts (1)

67-78: ⚠️ Potential issue | 🟠 Major

Treat create-only flags as opt-outs from auto-init.

shouldInitCurrentProject() still returns true for --force, --skills, --mcp, and --extension. In an existing repo, create-prisma --skills now falls into runInitCommand(), and those flags are silently dropped when the input is re-parsed as PrismaSetupCommandInput.

Suggested fix
 export async function shouldInitCurrentProject(
   input: {
     name?: string;
     template?: string;
+    force?: boolean;
+    skills?: boolean;
+    mcp?: boolean;
+    extension?: boolean;
   },
   projectDir = process.cwd()
 ): Promise<boolean> {
-  if (input.name || input.template) {
+  if (
+    input.name ||
+    input.template ||
+    input.force ||
+    input.skills ||
+    input.mcp ||
+    input.extension
+  ) {
     return false;
   }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fa40e948-d606-4956-bf19-856d26313f1a

📥 Commits

Reviewing files that changed from the base of the PR and between 3f248a2 and 00ab047.

📒 Files selected for processing (10)
  • README.md
  • src/commands/create.ts
  • src/commands/init.ts
  • src/tasks/setup-prisma.ts
  • src/templates/render-init-template.ts
  • src/types.ts
  • templates/init/prisma-instance.ts.hbs
  • templates/init/prisma.config.ts
  • templates/init/prisma/schema.prisma.hbs
  • templates/init/prisma/seed.ts.hbs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/tasks/setup-prisma.ts (1)

57-68: ⚠️ Potential issue | 🟠 Major

Accept src/client.ts when the current project is already packages/db.

The singleton candidate list only includes packages/db/src/client.ts, but finalizePrismaFiles() already falls back to src/client.ts once resolvePrismaProjectDir() returns the db package itself. Running init from repo/packages/db will therefore fail the required-file check even though the singleton exists.

💡 Proposed fix
 const requiredPrismaFileGroups = [
   ["prisma/schema.prisma", "packages/db/prisma/schema.prisma"],
   ["prisma/seed.ts", "packages/db/prisma/seed.ts"],
   ["prisma.config.ts", "packages/db/prisma.config.ts"],
   [
     "src/lib/prisma.ts",
     "src/lib/prisma.server.ts",
     "src/lib/server/prisma.ts",
     "server/utils/prisma.ts",
+    "src/client.ts",
     "packages/db/src/client.ts",
   ],
 ] as const;
src/index.ts (1)

16-31: ⚠️ Potential issue | 🔴 Critical

Register the init subcommand in the CLI router.

The router still only exposes create, so create-prisma init is not reachable from the built CLI even though runInitCommand() exists and this PR documents init as a public flow.

🚨 Suggested fix
 import { runCreateCommand } from "./commands/create";
+import { runInitCommand } from "./commands/init";
 import {
   CreateCommandInputSchema,
+  PrismaSetupCommandInputSchema,
   type CreateCommandInput,
 } from "./types";
 
 export const router = os.router({
   create: os
@@
     .handler(async ({ input }) => {
       await runCreateCommand(input ?? {}, {
         // Preserve smart init for `create-prisma`, but keep explicit
         // `create-prisma create` on the scaffolding path.
         allowInitCurrentProject: !usesExplicitCreateSubcommand(),
       });
     }),
+  init: os
+    .meta({
+      description: "Initialize Prisma in the current project",
+      negateBooleans: true,
+    })
+    .input(PrismaSetupCommandInputSchema.optional())
+    .handler(async ({ input }) => {
+      await runInitCommand(input ?? {});
+    }),
 });
♻️ Duplicate comments (3)
README.md (2)

41-50: ⚠️ Potential issue | 🟡 Minor

Add the explicit init usage example.

This section still only demonstrates the implicit smart path via bare create-prisma. Please add a create-prisma init example here so users can intentionally choose in-place initialization.


139-144: ⚠️ Potential issue | 🟡 Minor

Document Nuxt's singleton file path too.

The generated file list still omits server/utils/prisma.ts, which is one of the supported singleton locations in src/tasks/setup-prisma.ts. As written, the README under-documents the Nuxt layout.

src/commands/init.ts (1)

67-75: ⚠️ Potential issue | 🟠 Major

Keep create-only flags on the scaffolding path.

shouldInitCurrentProject() still only checks name and template, so commands like create-prisma --force, --skills, --mcp, or --extension inside an existing repo will still flip into init and silently ignore those create-only options.

💡 Suggested fix
 export async function shouldInitCurrentProject(
   input: {
     name?: string;
     template?: string;
+    force?: boolean;
+    skills?: boolean;
+    mcp?: boolean;
+    extension?: boolean;
   },
   projectDir = process.cwd()
 ): Promise<boolean> {
-  if (input.name || input.template) {
+  if (
+    input.name ||
+    input.template ||
+    input.force ||
+    input.skills ||
+    input.mcp ||
+    input.extension
+  ) {
     return false;
   }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 28b4dad1-2d5c-406e-8e77-a502354ee54a

📥 Commits

Reviewing files that changed from the base of the PR and between 00ab047 and fb0c0c3.

📒 Files selected for processing (7)
  • README.md
  • src/commands/create.ts
  • src/commands/init.ts
  • src/constants/dependencies.ts
  • src/index.ts
  • src/tasks/install.ts
  • src/tasks/setup-prisma.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
README.md (2)

41-45: ⚠️ Potential issue | 🟡 Minor

Document the explicit init command.

The PR introduces an explicit create-prisma init command, but this section only documents the implicit smart path. Users who want to intentionally initialize Prisma should be able to discover and use the explicit command.

📝 Suggested addition
 Initialize Prisma in the current project:
 
 ```bash
 create-prisma
+# or explicitly:
+create-prisma init
</details>

---

`35-45`: _⚠️ Potential issue_ | _🟡 Minor_

**Clarify the context-dependent behavior in the examples.**

Lines 35-39 and 41-45 show identical commands (`create-prisma`) but claim to produce different outcomes. Without additional context markers (such as "when `package.json` exists" vs. "in an empty directory"), readers cannot understand why the same command yields different behaviors. Consider adding inline comments or annotations to each code block that explicitly state the preconditions.



<details>
<summary>📝 Suggested clarification</summary>

```diff
 Create a new project in an empty directory:
 
 ```bash
+# Run this in an empty directory (no package.json)
 create-prisma

Initialize Prisma in the current project:

+# Run this in a directory with package.json
create-prisma
</details>

</blockquote></details>

</blockquote></details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: ASSERTIVE

**Plan**: Pro

**Run ID**: `10341b88-ce8f-4b1f-adf7-b795a1d9c2f2`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between fb0c0c3351862d15a9eb246ab1fa042c5f0641a1 and ef41fffdd1db2c09b53c5156ece18047ad2f2393.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `README.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@github-actions
Copy link

github-actions bot commented Mar 11, 2026

PR preview published

  • Version: 0.2.0-pr.17.25.1
  • Tag: pr17
  • Run with Bun: bunx create-prisma@pr17
  • Run with npm: npx create-prisma@pr17
  • Run with Yarn: yarn dlx create-prisma@pr17
  • Run with pnpm: pnpm dlx create-prisma@pr17
  • Run with Deno: deno run -A npm:create-prisma@pr17
  • Workflow run: https://github.com/prisma/create-prisma/actions/runs/22951906604

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant