---
id: start.server-function
kind: recipe
product: start
framework: react
locale: en
revision: 3
sourceCheckedOn: "2026-08-03"
versionRange: "^1"
verifiedAgainst: "@tanstack/react-start@1.168.34"
contentModel: 2
packages:
  - "@tanstack/react-start"
tasks:
  - "create-server-function"
  - "server-only-code"
  - "rpc"
sourceRefs:
  - "https://tanstack.com/start/latest/docs/framework/react/guide/server-functions"
---

# Create a server-only function

> Use createServerFn to define a same-origin, type-safe server RPC.

## Execution contract

- **Use when:** Use for app-internal, type-safe calls to databases, secrets, or other server-only capabilities.
- **Avoid when:** Use a Server Route instead for external systems, webhooks, or cross-origin clients.
- **Preconditions:** Choose GET or POST, define a runtime validator, and isolate implementation details in a server-only file.
- **Verification:** Test valid and invalid input, confirm client output excludes secrets and database code, and verify the result is serializable.
- **Failure mode:** TypeScript does not validate network input; malformed data reaching the handler indicates a missing or incorrect validator.
- **Security:** Authenticate and authorize inside every handler; route visibility is not a server authorization boundary.

## Use when

Code needs database, secret environment, or filesystem access and is called only by the current Start app. Use a Server Route for a public external API.

## Minimal implementation

The default method is GET. Use POST explicitly for operations with write side effects.

File: `src/server/issues.ts`

```ts
import { createServerFn } from '@tanstack/react-start'

export const getServerTime = createServerFn().handler(async () => {
  return { now: new Date().toISOString() }
})

export const createIssue = createServerFn({ method: 'POST' }).handler(
  async () => ({ ok: true }),
)

```

## Security boundary

A Server Function is same-origin RPC. Start installs its CSRF middleware automatically when there is no custom src/start.ts; once that file is customized, add createCsrfMiddleware explicitly. CSRF protection does not replace authentication, authorization, or input validation, and a typed caller does not make a request trusted.

## Official sources

- https://tanstack.com/start/latest/docs/framework/react/guide/server-functions
