From 1cc3265a3fdd2196bb728f79fc6b582fce6a2c2c Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 26 Oct 2026 22:05:49 -0300 Subject: [PATCH 1/5] docs: Replace the removed generator database feature flag with run mode configs --- .../01-server-fundamentals/03-configuration.md | 15 ++------------- docs/06-concepts/08-testing/03-configuration.md | 4 +--- docs/06-concepts/cli/commands/create/_create.md | 2 +- .../lookups/configuration-reference.md | 1 - 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/docs/06-concepts/01-server-fundamentals/03-configuration.md b/docs/06-concepts/01-server-fundamentals/03-configuration.md index 4b0f8148..627dfcfc 100644 --- a/docs/06-concepts/01-server-fundamentals/03-configuration.md +++ b/docs/06-concepts/01-server-fundamentals/03-configuration.md @@ -93,10 +93,10 @@ The three server blocks configure Serverpod's three servers: the API server your ### Database backends -Serverpod supports both PostgreSQL and SQLite as database backends. +Serverpod supports both PostgreSQL and SQLite as database backends. A server that does not use a database leaves the `database` section out of every run mode file, and `serverpod generate` then skips table code and migrations. :::warning -All run modes must use the same database backend: creating migrations fails otherwise. This also keeps your development environment consistent with production. +All run modes must use the same database backend, and either all of them or none of them configure a database: `serverpod generate` fails otherwise. This also keeps your development environment consistent with production. ::: #### PostgreSQL @@ -320,17 +320,6 @@ extraClasses: See the [serialization documentation](../data-and-the-database/models/custom-serialization) for implementing custom serializable classes. -### Features - -Control which Serverpod features are enabled: - -```yaml -features: - database: false -``` - -A server that does not use a database can set `database: false` to skip migrations and table generation. Projects created without a database, for example with `--no-database`, don't include this setting, so add it yourself. - ### Experimental features Experimental features are off by default and opted into per project with the `experimental_features` key. The current one is `databaseSync`, which enables [`database: sync`](../data-and-the-database/database/client-side-database#sync-tables-with-the-server) on table models; `all` enables every available feature: diff --git a/docs/06-concepts/08-testing/03-configuration.md b/docs/06-concepts/08-testing/03-configuration.md index 5120ae8d..9012e6c4 100644 --- a/docs/06-concepts/08-testing/03-configuration.md +++ b/docs/06-concepts/08-testing/03-configuration.md @@ -37,9 +37,7 @@ withServerpod( | `testServerOutputMode` | How much server output reaches your terminal. See [below](#server-output). | `TestServerOutputMode.normal` | :::note -When `config/generator.yaml` sets `features: database: false`, the generated `withServerpod` has no `applyMigrations`, `databaseInterceptor`, `rollbackDatabase`, or `runtimeParametersBuilder` parameter, so passing one is a compile error. Rollback is off in that case and there is nothing to migrate. - -Projects created without a database, for example with `--no-database`, don't include this setting, so add it and run `serverpod generate`. +When the run mode files configure no database, for example in a project created with `--no-database`, the generated `withServerpod` has no `applyMigrations`, `databaseInterceptor`, `rollbackDatabase`, or `runtimeParametersBuilder` parameter, so passing one is a compile error. Rollback is off in that case and there is nothing to migrate. ::: Set `serverDirectory` when tests run from somewhere other than the server package, such as the workspace root. Without it the server resolves those paths against the current directory, misses your config, and falls over later on whatever it needed from it. diff --git a/docs/06-concepts/cli/commands/create/_create.md b/docs/06-concepts/cli/commands/create/_create.md index 21a9fbb0..4d338dec 100644 --- a/docs/06-concepts/cli/commands/create/_create.md +++ b/docs/06-concepts/cli/commands/create/_create.md @@ -6,4 +6,4 @@ In an interactive terminal, `serverpod create` opens a setup screen where you ch The `--database`, `--redis`, `--auth`, `--webapp`, `--website`, and `--ide` flags apply only when the setup screen does not open, for example with `--no-interactive` or in CI. Without the setup screen, the project also gets Redis configuration and editor setup for Claude, Cursor, and VS Code, unless you pass `--no-redis` or choose editors with `--ide`. -To create a project without a database, deselect **Database (recommended)** under **Database & caching** on the setup screen, or pass `--no-interactive --no-database`. The new project still has the generator's database feature on, so set `database: false` under [`features`](../../../01-server-fundamentals/03-configuration.md#features) in `config/generator.yaml`, then run `serverpod generate`. +To create a project without a database, deselect **Database (recommended)** under **Database & caching** on the setup screen, or pass `--no-interactive --no-database`. The new project's run mode files then have no `database` section, which is what turns off database code generation. See [Database backends](../../../01-server-fundamentals/03-configuration.md#database-backends). diff --git a/docs/06-concepts/lookups/configuration-reference.md b/docs/06-concepts/lookups/configuration-reference.md index 96491a9d..1c3da9da 100644 --- a/docs/06-concepts/lookups/configuration-reference.md +++ b/docs/06-concepts/lookups/configuration-reference.md @@ -114,7 +114,6 @@ Options for `config/generator.yaml`, which configures `serverpod generate`. | modules | map | - | Module dependencies with optional nicknames. | | extraClasses | list | - | List of custom serializable classes to include in code generation. | | serialize_as_jsonb_by_default | bool | false | When true, all serializable fields default to `jsonb` storage instead of `json`. | -| features | map | \{database: true\} | Feature flags. Currently only `database` is supported. | | experimental_features | map | - | Experimental features. Available keys: `databaseSync` (enables `database: sync`) and `all`. | ## Related From 5caca1041d64496fc3071f782e50e245647ecb65 Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 26 Oct 2026 22:07:18 -0300 Subject: [PATCH 2/5] docs: Remove CLAUDE.md, which new projects no longer get --- .../01-server-fundamentals/01-your-serverpod-project.md | 3 +-- docs/11-upgrading/01-upgrade-to-four.md | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md b/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md index 738dfc5e..3cc3d028 100644 --- a/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md +++ b/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md @@ -27,7 +27,6 @@ myproject/ ├── AGENTS.md # Instructions for AI agents working in the project ├── .github/ # CI workflows: analyze, format, and test ├── .vscode/ # Attach-to-server debug configs and a serverpod start task, plus mcp.json if you picked VS Code -├── CLAUDE.md # If you picked Claude: loads AGENTS.md for Claude ├── .mcp.json, .claude/ # If you picked Claude: MCP config and skills ├── .cursor/ # If you picked Cursor: MCP config and skills ├── .codex/ # If you picked Codex: MCP config @@ -55,7 +54,7 @@ myproject/ └── assets/config.json # The server URL the app reads at startup ``` -The exact set depends on your create-time choices: the auth endpoints and sign-in screen come with authentication, the web pieces with the web server option, and the MCP configs and skills with the editors you picked. `AGENTS.md` is always created, and `CLAUDE.md` only when you pick Claude. +The exact set depends on your create-time choices: the auth endpoints and sign-in screen come with authentication, the web pieces with the web server option, and the MCP configs and skills with the editors you picked. `AGENTS.md` is always created.

diff --git a/docs/11-upgrading/01-upgrade-to-four.md b/docs/11-upgrading/01-upgrade-to-four.md index eda7da8c..dd21c2b3 100644 --- a/docs/11-upgrading/01-upgrade-to-four.md +++ b/docs/11-upgrading/01-upgrade-to-four.md @@ -275,7 +275,6 @@ In a folder that already has a Serverpod server, `serverpod create .` runs an up - `_server/docker-compose.yaml` and the workflows in `.github/workflows/`. - The scaffolded authentication endpoints in `_server/lib/src/auth/`, and the scaffolded web server files in `_server/lib/src/web/` and `_server/web/`. - `lib/main.dart`, `lib/client.dart`, and `lib/screens/greetings_screen.dart` in your Flutter app. -- `CLAUDE.md`, which becomes a pointer to an `AGENTS.md` file that the command doesn't create. The command also adds dependencies to your `pubspec.yaml` files. In an interactive terminal on a project that already has migrations, it only asks which editors to set up. In that case, it turns every other option off, so the rewritten files lose your setup. From b9a1ded737e388751314c2da2a4cc93915a1fc37 Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 26 Oct 2026 22:07:18 -0300 Subject: [PATCH 3/5] docs: List the Serverpod Cloud deploy workflow in the project tree --- .../01-server-fundamentals/01-your-serverpod-project.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md b/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md index 3cc3d028..7c61e10b 100644 --- a/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md +++ b/docs/06-concepts/01-server-fundamentals/01-your-serverpod-project.md @@ -25,7 +25,7 @@ That is the whole mental model: you work in the server and the app, and Serverpo myproject/ ├── pubspec.yaml # Workspace root: one `dart pub get` resolves all packages ├── AGENTS.md # Instructions for AI agents working in the project -├── .github/ # CI workflows: analyze, format, and test +├── .github/ # CI workflows: analyze, format, test, and deploy to Serverpod Cloud ├── .vscode/ # Attach-to-server debug configs and a serverpod start task, plus mcp.json if you picked VS Code ├── .mcp.json, .claude/ # If you picked Claude: MCP config and skills ├── .cursor/ # If you picked Cursor: MCP config and skills From 9aaf460c6bc22b10cbbcb99264e5310fab3eb0ab Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 26 Oct 2026 22:08:01 -0300 Subject: [PATCH 4/5] docs: Document the ephemeralDatabase test option --- docs/06-concepts/08-testing/01-get-started.md | 2 +- .../08-testing/03-configuration.md | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/06-concepts/08-testing/01-get-started.md b/docs/06-concepts/08-testing/01-get-started.md index ac51ad25..33466c4f 100644 --- a/docs/06-concepts/08-testing/01-get-started.md +++ b/docs/06-concepts/08-testing/01-get-started.md @@ -11,7 +11,7 @@ That means no separate server to start, no HTTP client to write, and no mocked d Two things follow from that: -- **Tests stay independent.** Anything a test writes to the database is rolled back once that test finishes, so tests never see each other's data and you do not clean up after yourself. Each `withServerpod` group also runs against its own temporary database, which is dropped when the group finishes. +- **Tests stay independent.** Anything a test writes to the database is rolled back once that test finishes, so tests never see each other's data and you do not clean up after yourself. By default, each `withServerpod` group also runs against its own temporary database, which is dropped when the group finishes. - **Each test sets its own scene.** A session builder decides what the server state looks like for a call, such as who is signed in. ## Set up diff --git a/docs/06-concepts/08-testing/03-configuration.md b/docs/06-concepts/08-testing/03-configuration.md index 9012e6c4..5ef82b54 100644 --- a/docs/06-concepts/08-testing/03-configuration.md +++ b/docs/06-concepts/08-testing/03-configuration.md @@ -26,6 +26,7 @@ withServerpod( | `configOverride` | A function that changes values in the loaded config before the server starts. | `null` | | `databaseInterceptor` | A [database interceptor](../data-and-the-database/database/database-interceptors) for the test server to use. | `null` | | `enableSessionLogging` | Whether session logging is on. | `false` | +| `ephemeralDatabase` | Whether the group gets its own empty database. See [below](#ephemeraldatabase). | `true` | | `experimentalFeatures` | Experimental features to enable, such as [diagnostic event handlers](../operations/exception-monitoring). | `null` | | `rollbackDatabase` | When database changes are rolled back. See [below](#rollbackdatabase). | `RollbackDatabase.afterEach` | | `runMode` | The run mode the server starts in. | `test` | @@ -37,7 +38,7 @@ withServerpod( | `testServerOutputMode` | How much server output reaches your terminal. See [below](#server-output). | `TestServerOutputMode.normal` | :::note -When the run mode files configure no database, for example in a project created with `--no-database`, the generated `withServerpod` has no `applyMigrations`, `databaseInterceptor`, `rollbackDatabase`, or `runtimeParametersBuilder` parameter, so passing one is a compile error. Rollback is off in that case and there is nothing to migrate. +When the run mode files configure no database, for example in a project created with `--no-database`, the generated `withServerpod` has no `applyMigrations`, `databaseInterceptor`, `ephemeralDatabase`, `rollbackDatabase`, or `runtimeParametersBuilder` parameter, so passing one is a compile error. Rollback is off in that case and there is nothing to migrate. ::: Set `serverDirectory` when tests run from somewhere other than the server package, such as the workspace root. Without it the server resolves those paths against the current directory, misses your config, and falls over later on whatever it needed from it. @@ -56,6 +57,22 @@ withServerpod( ); ``` +## Use an existing database {#ephemeraldatabase} + +Each `withServerpod` group runs against its own empty database, created when the group starts and dropped when it finishes. To run against the database configured for the run mode instead, for example one you seeded beforehand, pass `ephemeralDatabase: false`: + +```dart +withServerpod( + 'Given a seeded database', + (sessionBuilder, endpoints) { + /* test code */ + }, + ephemeralDatabase: false, +); +``` + +Serverpod then neither creates nor drops that database, and [`rollbackDatabase`](#rollbackdatabase) still decides whether the group's writes are rolled back. Groups that share the database can't run in parallel, so run their test files one at a time with `dart test --concurrency=1`. + ## Database rollback {#rollbackdatabase} By default each test runs inside a transaction that is rolled back when that test ends, so tests cannot see each other's data. Three values control this: From b3c1c3feaffad01e87c3ea8ab9338452814dadec Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 26 Oct 2026 22:10:42 -0300 Subject: [PATCH 5/5] docs: Note that a failed startup schema check no longer exits in development --- .../01-server-fundamentals/02-running-your-server.md | 2 +- .../03-data-and-the-database/02-database/13-migrations.md | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/06-concepts/01-server-fundamentals/02-running-your-server.md b/docs/06-concepts/01-server-fundamentals/02-running-your-server.md index 9def8f03..6af9fe17 100644 --- a/docs/06-concepts/01-server-fundamentals/02-running-your-server.md +++ b/docs/06-concepts/01-server-fundamentals/02-running-your-server.md @@ -116,7 +116,7 @@ Outside `serverpod start`, the server is a plain Dart program you can run yourse dart run bin/main.dart --apply-migrations ``` -The server accepts arguments that control how it starts: `--mode` selects the run mode, `--role` selects the [server role](#choose-a-server-role), and `--apply-migrations` applies pending migrations during startup. Without `--apply-migrations`, the server still checks the database schema at startup. On a mismatch, it exits with code 1 in the `development` run mode and logs a warning in other run modes. See the [run options reference](../lookups/configuration-reference#run-options) for the full list, and the [Deploy](../../deployments/deploy-to-serverpod-cloud) section for running in production. +The server accepts arguments that control how it starts: `--mode` selects the run mode, `--role` selects the [server role](#choose-a-server-role), and `--apply-migrations` applies pending migrations during startup. Without `--apply-migrations`, the server still checks the database schema at startup. On a mismatch, it logs a warning and keeps running. See the [run options reference](../lookups/configuration-reference#run-options) for the full list, and the [Deploy](../../deployments/deploy-to-serverpod-cloud) section for running in production. ## Choose a server role diff --git a/docs/06-concepts/03-data-and-the-database/02-database/13-migrations.md b/docs/06-concepts/03-data-and-the-database/02-database/13-migrations.md index 582188b3..38c10691 100644 --- a/docs/06-concepts/03-data-and-the-database/02-database/13-migrations.md +++ b/docs/06-concepts/03-data-and-the-database/02-database/13-migrations.md @@ -124,10 +124,7 @@ To apply migrations explicitly, start the server runtime with the `--apply-migra $ dart run bin/main.dart --apply-migrations ``` -If a migration fails, or the database doesn't match the latest migration afterward, the outcome depends on the run mode: - -- **Any run mode except `development`:** the server logs `Failed to apply database migrations.` or `Database does not match target state.` and keeps starting. -- **`development`:** the server exits with code 1. +If a migration fails, or the database doesn't match the latest migration afterward, the server logs `Failed to apply database migrations.` or `Database does not match target state.` and keeps starting. Requests that use the mismatched tables can fail until you fix the schema. Migrations can also be applied with the [maintenance role](../../server-fundamentals/running-your-server#choose-a-server-role). The server applies the migrations and then exits, which suits CI jobs and other automated processes. If a migration fails, or the database doesn't match the latest migration afterward, it exits with code 1 in every run mode, so the job fails.