Skip to content

docs: Added page "How it works"#496

Open
Swiftaxe wants to merge 2 commits into
mainfrom
docs/how-it-works
Open

docs: Added page "How it works"#496
Swiftaxe wants to merge 2 commits into
mainfrom
docs/how-it-works

Conversation

@Swiftaxe
Copy link
Copy Markdown
Collaborator

@Swiftaxe Swiftaxe commented May 13, 2026

Summary

The documentation currently lacks a dedicated page explaining Serverpod's architecture. This makes it harder for new users to understand how the different parts of the framework fit together.

This PR adds a new "How Serverpod works" page that provides a concise architectural overview, covering:

  • The project structure
  • Code generation
  • Request lifecycle
  • Full-stack type safety

The focus for this page is on how full-stack type safety is achieved through generating the client project and ORM classes.

Images

image image

Notes for reviewer

  • As we will move this page into "get started", I assume there is no need for an icon in the sidebar. For now, I kept the icon, previously used for Overview.
  • The page has a slightly shorter name in the menu, "How it works", while being called "How Serverpod works" on the page. This is intentional. "Serverpod" provides a better context and SEO perspective on the page, but is inferred in the menu.
  • Verify it covers the essential topics, so that a new user can easily grasp how the core of ServerPod works.
  • Verify the length is short enough to fit in the get started path.

Test plan

  • npm run build passes (no broken links).
  • Render /next locally and confirm the page reads well end-to-end.
  • Confirm the sidebar lists the new page correctly.

@Swiftaxe Swiftaxe requested a review from developerjamiu May 13, 2026 09:22
Copy link
Copy Markdown
Contributor

@developerjamiu developerjamiu left a comment

Choose a reason for hiding this comment

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

Document flows well top to bottom. Most of my line-level comments come from the doc templates and Viktor's feedback on the Introduction PR (#495).

Comment thread docs/03-how-it-works.md
title: How Serverpod works
sidebar_label: How it works
sidebar_class_name: sidebar-icon-overview
description: Serverpod's architecture, how project structure, code generation, and request lifecycle provide full-stack type safety
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Description should be a complete sentence per the doc templates.

Suggested change
description: Serverpod's architecture, how project structure, code generation, and request lifecycle provide full-stack type safety
description: Understand Serverpod's architecture: the three-package layout, the code generator, and the request lifecycle that gives you full-stack type safety.

Comment thread docs/03-how-it-works.md

# How Serverpod works

This page explains Serverpod's architecture: how the project structure, code generation, and request lifecycle work together to provide full-stack type safety.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Most templates says intro should drop the meta-statement like "This page explains"

Suggested change
This page explains Serverpod's architecture: how the project structure, code generation, and request lifecycle work together to provide full-stack type safety.
Serverpod is built around three Dart packages, a code generator, and a typed request lifecycle. Together they give you full-stack type safety from your database to your Flutter app.

Comment thread docs/03-how-it-works.md

The `_server` package holds your backend code, while the `_client` package acts as a bridge, providing the Flutter app with a typed API to call the server.

Because the `_client` package is auto-generated from the `_server` code, it stays in sync by construction. You do not write serialization code, HTTP calls, or API contracts by hand.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In previous review by Viktor, he suggested to not frame benefit as removing manual code i.e. "write serialization code, HTTP calls, or API contracts by hand" and also keep statements very simple

Suggested change
Because the `_client` package is auto-generated from the `_server` code, it stays in sync by construction. You do not write serialization code, HTTP calls, or API contracts by hand.
Change a model or add an endpoint, and the client follows automatically. The serialization and HTTP code are generated with it.

Comment thread docs/03-how-it-works.md

### Session

The `Session` parameter that every endpoint method receives is Serverpod's request context. It gives the method access to the database, cache, authenticated user information, and logging, all of which are scoped to the lifetime of that single request. It is not a singleton; each call gets its own `Session` instance.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Trying to avoid "singleton" keyword based on the above comment

Suggested change
The `Session` parameter that every endpoint method receives is Serverpod's request context. It gives the method access to the database, cache, authenticated user information, and logging, all of which are scoped to the lifetime of that single request. It is not a singleton; each call gets its own `Session` instance.
The `Session` parameter that every endpoint method receives is the context for that single request. It gives access to the database, cache, signed-in user, and logging, all available only while the request runs. Each call gets its own `Session`.

Comment thread docs/03-how-it-works.md

## Type safety across the stack

Type safety across the entire stack, from the database to your Flutter app, is guaranteed because Serverpod's model files (`.spy.yaml`) are the single source of truth. When code is generated, the same Dart class is used for database queries, server-side logic, and the client-side app.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Type safety across the entire stack, from the database to your Flutter app, is guaranteed because Serverpod's model files (`.spy.yaml`) are the single source of truth. When code is generated, the same Dart class is used for database queries, server-side logic, and the client-side app.
Type safety across the entire stack, from the database to your Flutter app, is guaranteed because Serverpod's model files (`.spy.yaml`) are the single source of truth. When code is generated, the same Dart class is used in database queries, server logic, and your Flutter app.

Comment thread docs/03-how-it-works.md

## Code generation

The purpose of code generation is to eliminate boilerplate and provide type-safety. Serverpod continuously watches for changes in your `_server` package and the generator automatically creates the necessary code.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removed the filler words; The purpose and continously

Suggested change
The purpose of code generation is to eliminate boilerplate and provide type-safety. Serverpod continuously watches for changes in your `_server` package and the generator automatically creates the necessary code.
Code generation cuts boilerplate and keeps types in sync between server and app. Serverpod watches your `_server` package as you edit and runs the generator automatically.

Comment thread docs/03-how-it-works.md
Thanks to the generated client, calling a server endpoint from your Flutter app feels like a local method call. You do not need to write any networking or serialization code.

```dart
var result = await client.greeting.hello('World');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Dart convention: var should be final for non-reassigned locals.

Suggested change
var result = await client.greeting.hello('World');
final result = await client.greeting.hello('World');

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.

2 participants