create-prisma 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,6 +15,10 @@ bunx create-prisma@latest my-app
15
15
 
16
16
  The CLI initializes Prisma 8 with `prisma@latest`, installs dependencies, emits the contract, and generates a deployable Composer app. PostgreSQL projects use Composer's native Prisma Postgres provider, including migrations and a typed runtime client.
17
17
 
18
+ PostgreSQL apps with Composer include `@prisma/dev` as a project devDependency for
19
+ local Postgres. In a monorepo it belongs at the root, where Composer runs. Prisma 8
20
+ does not include this runtime itself. MongoDB and Deno-only apps do not need it.
21
+
18
22
  For npm, use 11.6.0 or newer, which includes the [upstream resolver fix](https://github.com/npm/cli/pull/8448).
19
23
  Older npm releases can crash resolving the dependency tree (`Cannot read properties of null (reading 'edgesOut')`). Run
20
24
  `npm install --global npm@11` to update. create-prisma checks the selected npm
@@ -44,6 +48,7 @@ workspace. Choosing another workspace also updates the Prisma CLI's active works
44
48
  - `elysia`
45
49
  - `nest`
46
50
  - `next`
51
+ - `turborepo` (Hello World Node.js server in `apps/server`, shared Prisma package in `packages/database`)
47
52
  - `svelte` (SvelteKit)
48
53
  - `astro`
49
54
  - `nuxt`
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as ApplicationLayer } from "./json-output-BEzP-dBw.mjs";
2
+ import { a as ApplicationLayer } from "./json-output-Bpk7rG2T.mjs";
3
3
  import { runCreatePrismaCli } from "./index.mjs";
4
4
  import { Effect } from "effect";
5
5
  import { NodeRuntime } from "@effect/platform-node-shared";
package/dist/index.d.mts CHANGED
@@ -42,10 +42,10 @@ declare const DatabaseProviderSchema: Schema.Literals<readonly ["postgres", "mon
42
42
  declare const PackageManagerSchema: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
43
43
  declare const AuthoringStyleSchema: Schema.Literals<readonly ["psl", "typescript"]>;
44
44
  declare const AgentSkillTargetSchema: Schema.Literals<readonly ["claude", "cursor", "agents", "devin"]>;
45
- declare const CreateTemplateSchema: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
45
+ declare const CreateTemplateSchema: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
46
46
  declare const CreateCommandInputSchema: Schema.Struct<{
47
47
  readonly name: Schema.optionalKey<Schema.Trim>;
48
- readonly template: Schema.optionalKey<Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>>;
48
+ readonly template: Schema.optionalKey<Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>>;
49
49
  readonly force: Schema.optionalKey<Schema.Boolean>;
50
50
  readonly provider: Schema.optionalKey<Schema.Literals<readonly ["postgres", "mongo"]>>;
51
51
  readonly authoring: Schema.optionalKey<Schema.Literals<readonly ["psl", "typescript"]>>;
@@ -75,7 +75,7 @@ type CreateNextStep = typeof CreateNextStepSchema.Type;
75
75
  declare const CreateProjectResultSchema: Schema.Struct<{
76
76
  readonly name: Schema.String;
77
77
  readonly path: Schema.String;
78
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
78
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
79
79
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
80
80
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
81
81
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -88,7 +88,7 @@ declare const CreateCommandSuccessResultSchema: Schema.Struct<{
88
88
  readonly project: Schema.Struct<{
89
89
  readonly name: Schema.String;
90
90
  readonly path: Schema.String;
91
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
91
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
92
92
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
93
93
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
94
94
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -124,7 +124,7 @@ declare const CreateCommandFailureResultSchema: Schema.Struct<{
124
124
  readonly project: Schema.optionalKey<Schema.Struct<{
125
125
  readonly name: Schema.String;
126
126
  readonly path: Schema.String;
127
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
127
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
128
128
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
129
129
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
130
130
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -137,7 +137,7 @@ declare const CreateCommandResultSchema: Schema.Union<readonly [Schema.Struct<{
137
137
  readonly project: Schema.Struct<{
138
138
  readonly name: Schema.String;
139
139
  readonly path: Schema.String;
140
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
140
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
141
141
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
142
142
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
143
143
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -171,7 +171,7 @@ declare const CreateCommandResultSchema: Schema.Union<readonly [Schema.Struct<{
171
171
  readonly project: Schema.optionalKey<Schema.Struct<{
172
172
  readonly name: Schema.String;
173
173
  readonly path: Schema.String;
174
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
174
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
175
175
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
176
176
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
177
177
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -183,7 +183,7 @@ type CreateCommandResult = typeof CreateCommandResultSchema.Type;
183
183
  declare const createPrismaCommand: Command.Command<"create-prisma", {
184
184
  readonly projectName: string | undefined;
185
185
  readonly name: string | undefined;
186
- readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
186
+ readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "turborepo" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
187
187
  readonly provider: "postgres" | "mongo" | undefined;
188
188
  readonly authoring: "psl" | "typescript" | undefined;
189
189
  readonly packageManager: "npm" | "pnpm" | "yarn" | "bun" | "deno" | undefined;
@@ -198,7 +198,7 @@ declare const createPrismaCommand: Command.Command<"create-prisma", {
198
198
  declare function createCreatePrismaCli(): Command.Command<"create-prisma", {
199
199
  readonly projectName: string | undefined;
200
200
  readonly name: string | undefined;
201
- readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
201
+ readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "turborepo" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
202
202
  readonly provider: "postgres" | "mongo" | undefined;
203
203
  readonly authoring: "psl" | "typescript" | undefined;
204
204
  readonly packageManager: "npm" | "pnpm" | "yarn" | "bun" | "deno" | undefined;
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { _ as authoringStyles, b as normalizeDatabaseProvider, c as CreateCommandResultSchema, d as AuthoringStyleSchema, f as CreateCommandInputSchema, g as agentSkillTargets, h as PackageManagerSchema, i as getErrorMessage, l as createCommandFailureResult, m as DatabaseProviderSchema, n as writeJsonResult, o as applicationRuntime, p as CreateTemplateSchema, r as runCreateCommandEffect, s as CREATE_PRISMA_RESULT_SCHEMA_VERSION, t as isJsonOutputRequested, u as AgentSkillTargetSchema, v as createTemplates, x as packageManagers, y as databaseProviderInputs } from "./json-output-BEzP-dBw.mjs";
2
+ import { _ as authoringStyles, b as normalizeDatabaseProvider, c as CreateCommandResultSchema, d as AuthoringStyleSchema, f as CreateCommandInputSchema, g as agentSkillTargets, h as PackageManagerSchema, i as getErrorMessage, l as createCommandFailureResult, m as DatabaseProviderSchema, n as writeJsonResult, o as applicationRuntime, p as CreateTemplateSchema, r as runCreateCommandEffect, s as CREATE_PRISMA_RESULT_SCHEMA_VERSION, t as isJsonOutputRequested, u as AgentSkillTargetSchema, v as createTemplates, x as packageManagers, y as databaseProviderInputs } from "./json-output-Bpk7rG2T.mjs";
3
3
  import { Console, Effect, Option } from "effect";
4
4
  import { Argument, CliError, Command, Flag } from "effect/unstable/cli";
5
5
 
6
6
  //#region src/index.ts
7
- const CLI_VERSION = "0.12.1";
7
+ const CLI_VERSION = "0.13.0";
8
8
  const optionalArgument = (name, description) => Argument.string(name).pipe(Argument.withDescription(description), Argument.optional, Argument.map(Option.getOrUndefined));
9
9
  const optionalBoolean = (name, description) => Flag.boolean(name).pipe(Flag.withDescription(description), Flag.optional, Flag.map(Option.getOrUndefined));
10
10
  const optionalString = (name, description) => Flag.string(name).pipe(Flag.withDescription(description), Flag.optional, Flag.map(Option.getOrUndefined));
@@ -130,6 +130,7 @@ const createTemplates = [
130
130
  "elysia",
131
131
  "nest",
132
132
  "next",
133
+ "turborepo",
133
134
  "svelte",
134
135
  "astro",
135
136
  "nuxt",
@@ -388,7 +389,7 @@ const getAnonymousIdEffect = Effect.fn("Telemetry.getAnonymousId")(function* ()
388
389
  return anonymousId;
389
390
  });
390
391
  const getCommonProperties = () => ({
391
- "cli-version": "0.12.1",
392
+ "cli-version": "0.13.0",
392
393
  "node-version": process.version,
393
394
  platform: process.platform,
394
395
  arch: process.arch
@@ -767,9 +768,10 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
767
768
  for (const relativePath of entries) {
768
769
  const templateFilePath = path.join(opts.templateRoot, relativePath);
769
770
  if ((yield* fs.stat(templateFilePath)).type !== "File") continue;
771
+ const renderedRelativePath = stripHbsExtension(relativePath);
770
772
  yield* renderTemplateFileEffect({
771
773
  templateFilePath,
772
- outputPath: path.join(opts.outputDir, stripHbsExtension(relativePath)),
774
+ outputPath: path.join(opts.outputDir, opts.mapRelativeOutputPath?.(renderedRelativePath) ?? renderedRelativePath),
773
775
  context: opts.context
774
776
  });
775
777
  }
@@ -777,11 +779,17 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
777
779
 
778
780
  //#endregion
779
781
  //#region src/templates/render-create-template.ts
782
+ const DEFAULT_PRISMA_SOURCE_DIR = "src/prisma";
783
+ const TURBOREPO_PRISMA_SOURCE_DIR = "packages/database/src";
784
+ function getCreatePrismaSourceDir(template) {
785
+ return template === "turborepo" ? TURBOREPO_PRISMA_SOURCE_DIR : DEFAULT_PRISMA_SOURCE_DIR;
786
+ }
780
787
  const tsdownEntries = {
781
788
  minimal: "src/index.ts",
782
789
  hono: "src/index.ts",
783
790
  elysia: "src/index.ts",
784
- nest: "src/main.ts"
791
+ nest: "src/main.ts",
792
+ turborepo: "src/index.ts"
785
793
  };
786
794
  function createTemplateContext(options) {
787
795
  return {
@@ -798,7 +806,14 @@ const scaffoldCreateSharedTemplatesEffect = Effect.fn("Templates.scaffoldShared"
798
806
  yield* renderTemplateTreeEffect({
799
807
  templateRoot: yield* resolveTemplatesDirEffect("templates/create/_shared"),
800
808
  outputDir: options.projectDir,
801
- context: createTemplateContext(options)
809
+ context: createTemplateContext(options),
810
+ mapRelativeOutputPath(relativePath) {
811
+ if (options.template !== "turborepo") return relativePath;
812
+ if (relativePath === "tsdown.config.ts") return path.join("apps/server", relativePath);
813
+ const relativePrismaPath = path.relative(DEFAULT_PRISMA_SOURCE_DIR, relativePath);
814
+ if (relativePrismaPath === ".." || relativePrismaPath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePrismaPath)) return relativePath;
815
+ return path.join(TURBOREPO_PRISMA_SOURCE_DIR, relativePrismaPath);
816
+ }
802
817
  });
803
818
  });
804
819
  const scaffoldCreatePackageManagerTemplatesEffect = Effect.fn("Templates.scaffoldPackageManager")(function* (options) {
@@ -828,6 +843,7 @@ const dependencyVersionMap = {
828
843
  "@elysiajs/node": "^1.4.5",
829
844
  "@prisma/composer": "0.19.0",
830
845
  "@prisma/composer-prisma-cloud": "0.19.0",
846
+ "@prisma/dev": "0.25.2",
831
847
  "@prisma/orm-mongo": "8.0.0-rc.10",
832
848
  "@prisma/orm-postgres": "8.0.0-rc.10",
833
849
  "@sveltejs/adapter-node": "^5.3.2",
@@ -842,6 +858,7 @@ const dependencyVersionMap = {
842
858
  prisma: "latest",
843
859
  "temporal-polyfill": "^1.0.4",
844
860
  tsdown: "^0.22.14",
861
+ turbo: "2.10.12",
845
862
  tsx: "^4.21.0",
846
863
  typescript: "^5.9.3"
847
864
  };
@@ -853,7 +870,7 @@ function getDependencyVersion(packageName) {
853
870
  function usesTsdown(template) {
854
871
  return template === "minimal" || template === "hono" || template === "elysia" || template === "nest";
855
872
  }
856
- function getCreateTemplateDependencies(template, _packageManager) {
873
+ function getCreateTemplateDependencies(template, packageManager) {
857
874
  const dependencies = [
858
875
  "@prisma/composer",
859
876
  "@prisma/composer-prisma-cloud",
@@ -872,11 +889,31 @@ function getCreateTemplateDependencies(template, _packageManager) {
872
889
  if (template === "svelte") devDependencies.push("@sveltejs/adapter-node");
873
890
  if (template === "astro") dependencies.push("@astrojs/node");
874
891
  if (template === "tanstack-start") devDependencies.push("nitro");
875
- return [{
892
+ if (template === "turborepo") devDependencies.push("turbo", "typescript");
893
+ const targets = [{
876
894
  packageJsonPath: "package.json",
877
895
  dependencies,
878
896
  devDependencies
879
897
  }];
898
+ if (template === "turborepo") {
899
+ targets.push({
900
+ packageJsonPath: "apps/server/package.json",
901
+ dependencies: [],
902
+ devDependencies: [
903
+ "@types/node",
904
+ "tsdown",
905
+ "tsx",
906
+ "typescript"
907
+ ],
908
+ customDependencies: { "@repo/database": packageManager === "npm" ? "*" : "workspace:*" }
909
+ });
910
+ targets.push({
911
+ packageJsonPath: "packages/database/package.json",
912
+ dependencies: [],
913
+ devDependencies: ["typescript"]
914
+ });
915
+ }
916
+ return targets;
880
917
  }
881
918
 
882
919
  //#endregion
@@ -995,16 +1032,25 @@ const addPackageDependencyEffect = Effect.fn("Dependencies.add")(function* (opts
995
1032
  yield* writePackageJson(packageJsonPath, packageJson);
996
1033
  });
997
1034
  const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(function* (provider, packageManager, _authoring, projectDir = process.cwd(), options = {}) {
998
- const dependencies = [getDbPackages(provider)];
999
- if (provider === "postgres" && packageManager !== "deno") dependencies.push("temporal-polyfill");
1000
- if (provider === "mongo") dependencies.push("arktype", "mongodb");
1035
+ const databaseDependencies = [getDbPackages(provider)];
1036
+ const devDependencies = ["@types/node", "prisma"];
1037
+ if (provider === "postgres" && packageManager !== "deno") {
1038
+ databaseDependencies.push("temporal-polyfill");
1039
+ devDependencies.push("@prisma/dev");
1040
+ }
1041
+ if (provider === "mongo") databaseDependencies.push("arktype", "mongodb");
1042
+ const dependencies = options.template === "turborepo" ? [getDbPackages(provider), ...provider === "mongo" ? ["arktype"] : []] : [...databaseDependencies];
1001
1043
  if (packageManager === "deno") dependencies.push("dotenv");
1002
1044
  yield* addPackageDependencyEffect({
1003
1045
  dependencies,
1004
- devDependencies: ["@types/node", "prisma"],
1046
+ devDependencies,
1005
1047
  scripts: getPrismaScriptMap(packageManager, options.skillsSync ?? true),
1006
1048
  projectDir
1007
1049
  });
1050
+ if (options.template === "turborepo") yield* addPackageDependencyEffect({
1051
+ dependencies: databaseDependencies,
1052
+ projectDir: path.join(projectDir, "packages/database")
1053
+ });
1008
1054
  });
1009
1055
  const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTemplate")(function* (opts) {
1010
1056
  const projectDir = opts.projectDir ?? process.cwd();
@@ -1013,7 +1059,7 @@ const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTempl
1013
1059
  dependencies: target.dependencies,
1014
1060
  devDependencies: target.devDependencies,
1015
1061
  customDependencies: target.customDependencies,
1016
- scripts: getComposerScriptMap(opts.packageManager),
1062
+ scripts: target.packageJsonPath === "package.json" ? getComposerScriptMap(opts.packageManager) : void 0,
1017
1063
  projectDir: path.join(projectDir, path.dirname(target.packageJsonPath))
1018
1064
  });
1019
1065
  const packageJsonPath = path.join(projectDir, "package.json");
@@ -1508,7 +1554,7 @@ const initializeGitRepositoryEffect = Effect.fn("Git.initialize")(function* (pro
1508
1554
 
1509
1555
  //#endregion
1510
1556
  //#region src/tasks/prisma-setup/commands.ts
1511
- const getContractPath = (authoring) => `src/prisma/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1557
+ const getContractPath = (authoring, template) => `${getCreatePrismaSourceDir(template)}/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1512
1558
  const getInitTarget = (provider) => provider === "mongo" ? "mongodb" : "postgres";
1513
1559
  const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, projectDir, args) {
1514
1560
  const invocation = getLocalPackageBinaryArgs(context.packageManager, "prisma", args);
@@ -1526,7 +1572,7 @@ const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, project
1526
1572
  ...context.verbose ? { onStderrLine: (line) => log.message(redactSecrets(line), { output: context.output }) } : {}
1527
1573
  });
1528
1574
  });
1529
- const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false) {
1575
+ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false, template = "minimal") {
1530
1576
  yield* runPrismaCli(context, projectDir, [
1531
1577
  "orm",
1532
1578
  "init",
@@ -1537,7 +1583,7 @@ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectD
1537
1583
  "--authoring",
1538
1584
  context.authoring,
1539
1585
  "--schema-path",
1540
- getContractPath(context.authoring),
1586
+ getContractPath(context.authoring, template),
1541
1587
  "--skip-install"
1542
1588
  ]);
1543
1589
  if (context.packageManager === "deno") {
@@ -1805,14 +1851,17 @@ const executePrismaSetupContextEffect = Effect.fn("PrismaSetup.execute")(functio
1805
1851
  packageManager: context.packageManager,
1806
1852
  skillAgents: context.skillAgents
1807
1853
  }), "configure_project", "project_configuration_failed");
1808
- yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, { skillsSync: context.skillAgents.length > 0 }), "configure_project", "project_configuration_failed");
1854
+ yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
1855
+ skillsSync: context.skillAgents.length > 0,
1856
+ template
1857
+ }), "configure_project", "project_configuration_failed");
1809
1858
  yield* Effect.sync(() => progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`));
1810
1859
  yield* atCreateStage(installProjectDependenciesEffect(context.packageManager, projectDir, {
1811
1860
  verbose: context.verbose,
1812
1861
  json: context.json
1813
1862
  }), "install_dependencies", "dependency_install_failed");
1814
1863
  yield* Effect.sync(() => progress?.message("Preparing Prisma 8 project files..."));
1815
- yield* atCreateStage(runPrismaInit(context, projectDir, options.force), "initialize_prisma", "prisma_init_failed");
1864
+ yield* atCreateStage(runPrismaInit(context, projectDir, options.force, template), "initialize_prisma", "prisma_init_failed");
1816
1865
  yield* atCreateStage(Effect.gen(function* () {
1817
1866
  yield* scaffoldCreateSharedTemplatesEffect({
1818
1867
  projectDir,
@@ -1995,6 +2044,11 @@ const promptForCreateTemplate = Effect.fn("Prompts.template")(function* (output)
1995
2044
  label: "Next.js",
1996
2045
  hint: "Full-stack React app with App Router"
1997
2046
  },
2047
+ {
2048
+ value: "turborepo",
2049
+ label: "Monorepo (Turborepo)",
2050
+ hint: "Hello World server with a shared Prisma database package"
2051
+ },
1998
2052
  {
1999
2053
  value: "svelte",
2000
2054
  label: "SvelteKit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "private": false,
5
5
  "description": "Create Prisma 8 projects with first-party templates and great DX.",
6
6
  "homepage": "https://github.com/prisma/create-prisma",
@@ -1,4 +1,9 @@
1
1
  {{#if (eq packageManager "pnpm")}}
2
+ {{#if (eq template "turborepo")}}
3
+ packages:
4
+ - "apps/*"
5
+ - "packages/*"
6
+ {{/if}}
2
7
  allowBuilds:
3
8
  esbuild: true
4
9
  msgpackr-extract: true
@@ -1,11 +1,11 @@
1
1
  {{#if (eq authoring "typescript")}}
2
- src/prisma/generated/contract.json linguist-generated
3
- src/prisma/generated/contract.d.ts linguist-generated
2
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated/contract.json linguist-generated
3
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated/contract.d.ts linguist-generated
4
4
  {{else}}
5
- src/prisma/contract.json linguist-generated
6
- src/prisma/contract.d.ts linguist-generated
5
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract.json linguist-generated
6
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract.d.ts linguist-generated
7
7
  {{/if}}
8
- src/prisma/ops.json linguist-generated
9
- src/prisma/migration.json linguist-generated
8
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/ops.json linguist-generated
9
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/migration.json linguist-generated
10
10
  migrations/snapshots/**/contract.json linguist-generated
11
11
  migrations/snapshots/**/contract.d.ts linguist-generated
@@ -31,6 +31,50 @@ deno task contract:emit
31
31
  ```
32
32
 
33
33
  Prisma Compute does not support Deno deployments yet.
34
+ {{else if (eq template "turborepo")}}
35
+ A minimal Prisma 8 monorepo with Turborepo and a plain Node.js HTTP server.
36
+
37
+ ## Workspace layout
38
+
39
+ - `apps/server` — Hello World server; `/users` reads from the shared database package
40
+ - `packages/database` — Prisma contract, generated artifacts, runtime client, and seed data
41
+ - `module.ts` and `service.ts` — Composer deployment topology
42
+
43
+ ## Run locally
44
+
45
+ ```bash
46
+ {{runScriptCommand packageManager "dev:composer"}}
47
+ ```
48
+
49
+ This builds the workspace and starts it with Composer. PostgreSQL projects get a local Prisma Postgres database and apply the committed migrations automatically.
50
+
51
+ ## Deploy
52
+
53
+ ```bash
54
+ {{runScriptCommand packageManager "deploy"}}
55
+ ```
56
+
57
+ The deploy script builds the server with tsdown, provisions Prisma Postgres when selected, applies migrations, and deploys the server to Prisma Compute.
58
+
59
+ The home page returns `Hello World!` without querying the database. Visiting `/users` queries the shared Prisma package and inserts starter users idempotently from `packages/database/src/seed.ts`.
60
+
61
+ {{#if (eq provider "mongo")}}
62
+ MongoDB is not provisioned by Composer. Set `MONGODB_URL` before running Composer locally or deploying.
63
+ {{/if}}
64
+
65
+ ## Prisma
66
+
67
+ - Contract: `packages/database/src/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}`
68
+ - Prisma and Composer config: `prisma.config.ts`
69
+ - Composer app: `module.ts` and `service.ts`
70
+
71
+ After changing the contract, run:
72
+
73
+ ```bash
74
+ {{runScriptCommand packageManager "contract:emit"}}
75
+ ```
76
+
77
+ To run the workspace's development tasks directly, use `{{runScriptCommand packageManager "dev"}}`. This direct mode requires `{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}`.
34
78
  {{else}}
35
79
  A minimal {{template}} app with Prisma 8 and Prisma Composer.
36
80
 
@@ -3,7 +3,7 @@ import { module } from "@prisma/composer";
3
3
  {{#if (eq provider "postgres")}}
4
4
  import { postgres } from "@prisma/composer-prisma-cloud/orm";
5
5
 
6
- import { appContract } from "./src/prisma/composer.ts";
6
+ import { appContract } from "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/composer.ts";
7
7
  {{else}}
8
8
  import { envSecret } from "@prisma/composer-prisma-cloud";
9
9
  {{/if}}
@@ -5,9 +5,9 @@ import { defineConfig as ormConfig } from "@prisma/orm-{{#if (eq provider "postg
5
5
 
6
6
  export default definePrismaConfig({
7
7
  orm: ormConfig({
8
- contract: "./src/prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
8
+ contract: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
9
9
  {{#if (eq authoring "typescript")}}
10
- output: "./src/prisma/generated",
10
+ output: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated",
11
11
  {{/if}}
12
12
  db: {
13
13
  connection: process.env.{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}!,
@@ -23,9 +23,9 @@ export default definePrismaConfig({
23
23
  agents: [{{#each skillAgents}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}],
24
24
  },
25
25
  orm: ormConfig({
26
- contract: "./src/prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
26
+ contract: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
27
27
  {{#if (eq authoring "typescript")}}
28
- output: "./src/prisma/generated",
28
+ output: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated",
29
29
  {{/if}}
30
30
  db: {
31
31
  connection: process.env.{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}!,
@@ -12,7 +12,7 @@ import { compute } from "@prisma/composer-prisma-cloud";
12
12
  {{#if (eq provider "postgres")}}
13
13
  import { postgres } from "@prisma/composer-prisma-cloud/orm";
14
14
 
15
- import { appContract } from "./src/prisma/composer.ts";
15
+ import { appContract } from "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/composer.ts";
16
16
  {{/if}}
17
17
 
18
18
  export default compute({
@@ -29,6 +29,8 @@ export default compute({
29
29
  {{/if}}
30
30
  {{#if (eq template "next")}}
31
31
  build: nextjs({ module: import.meta.url, appDir: "." }),
32
+ {{else if (eq template "turborepo")}}
33
+ build: node({ module: import.meta.url, entry: "./apps/server/dist/server.mjs" }),
32
34
  {{else if (eq template "svelte")}}
33
35
  build: node({ module: import.meta.url, dir: "./build", entry: "index.js" }),
34
36
  {{else if (eq template "astro")}}
@@ -14,7 +14,7 @@ export const db = postgres<Contract>({ contractJson, url: databaseUrl });
14
14
  {{else}}
15
15
  import "temporal-polyfill/global";
16
16
 
17
- import service from "../../service.ts";
17
+ import service from "{{#if (eq template "turborepo")}}../../../service.ts{{else}}../../service.ts{{/if}}";
18
18
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
19
19
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };
20
20
 
@@ -35,7 +35,7 @@ export const db =
35
35
  {{else}}
36
36
  import mongo from "@prisma/orm-mongo/runtime";
37
37
 
38
- import service from "../../service.ts";
38
+ import service from "{{#if (eq template "turborepo")}}../../../service.ts{{else}}../../service.ts{{/if}}";
39
39
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
40
40
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };
41
41
 
@@ -0,0 +1,3 @@
1
+ {{#if (eq packageManager "yarn")}}
2
+ nodeLinker: node-modules
3
+ {{/if}}
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@repo/server",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/index.ts",
8
+ "build": "tsdown",
9
+ "start": "node dist/server.mjs",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "engines": {
13
+ "node": "^22.18.0 || >=24.11.0"
14
+ }
15
+ }
@@ -0,0 +1,31 @@
1
+ import { createServer } from "node:http";
2
+
3
+ import { listUsers } from "@repo/database";
4
+
5
+ const port = Number(process.env.PORT ?? 3000);
6
+
7
+ createServer(async (request, response) => {
8
+ if (request.url === "/") {
9
+ response.writeHead(200, { "content-type": "text/plain" });
10
+ response.end("Hello World!");
11
+ return;
12
+ }
13
+
14
+ if (request.url !== "/users") {
15
+ response.writeHead(404, { "content-type": "text/plain" });
16
+ response.end("Not found");
17
+ return;
18
+ }
19
+
20
+ try {
21
+ const users = await listUsers();
22
+ response.writeHead(200, { "content-type": "application/json" });
23
+ response.end(JSON.stringify({ users }));
24
+ } catch (error) {
25
+ console.error("Failed to query users:", error);
26
+ response.writeHead(500, { "content-type": "application/json" });
27
+ response.end(JSON.stringify({ error: "Could not query users yet." }));
28
+ }
29
+ }).listen(port, "0.0.0.0", () => {
30
+ console.log(`Server running at http://localhost:${port}`);
31
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*.ts", "tsdown.config.ts"]
4
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ {{#if (packageManagerManifestValue packageManager)}}
6
+ "packageManager": "{{packageManagerManifestValue packageManager}}",
7
+ {{/if}}
8
+ "type": "module",
9
+ "workspaces": [
10
+ "apps/*",
11
+ "packages/*"
12
+ ],
13
+ "scripts": {
14
+ "build": "turbo run build",
15
+ "dev": "turbo run dev",
16
+ "start": "turbo run start",
17
+ "typecheck": "tsc --noEmit && turbo run typecheck"
18
+ },
19
+ "devDependencies": {}
20
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "@repo/database",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/users.ts",
8
+ "./db": "./src/db.ts"
9
+ },
10
+ "scripts": {
11
+ "typecheck": "tsc --noEmit --project tsconfig.json"
12
+ }
13
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*.ts"]
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "allowImportingTsExtensions": true,
8
+ "noEmit": true,
9
+ "resolveJsonModule": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "types": ["node"]
13
+ },
14
+ "include": [
15
+ "module.ts",
16
+ "service.ts",
17
+ "prisma.config.ts",
18
+ "prisma-composer.config.ts",
19
+ "packages/**/*.ts"
20
+ ],
21
+ "exclude": ["node_modules"]
22
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "globalDependencies": ["service.ts", "packages/database/src/**"],
4
+ "globalPassThroughEnv": ["PORT", "DATABASE_URL", "MONGODB_URL"],
5
+ "tasks": {
6
+ "build": {
7
+ "dependsOn": ["^build"],
8
+ "outputs": ["dist/**"]
9
+ },
10
+ "dev": {
11
+ "cache": false,
12
+ "persistent": true
13
+ },
14
+ "start": {
15
+ "cache": false,
16
+ "dependsOn": ["build"],
17
+ "persistent": true
18
+ },
19
+ "typecheck": {
20
+ "dependsOn": ["^typecheck"]
21
+ }
22
+ }
23
+ }