> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pocketbase/pocketbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get your PocketBase backend running in minutes and create your first collection.

This guide walks you through installing PocketBase, starting the server, and creating your first database collection. You'll have a working REST API in under 5 minutes.

## Prerequisites

No dependencies required! PocketBase is a single executable that runs on macOS, Linux, Windows, and FreeBSD.

## Start your first instance

<Steps>
  <Step title="Download and extract">
    Download the latest release for your platform from [GitHub](https://github.com/pocketbase/pocketbase/releases):

    <CodeGroup>
      ```bash macOS/Linux theme={null}
      # Download (replace VERSION with the latest version)
      wget https://github.com/pocketbase/pocketbase/releases/download/vVERSION/pocketbase_VERSION_linux_amd64.zip

      # Extract
      unzip pocketbase_VERSION_linux_amd64.zip

      # Make executable
      chmod +x pocketbase
      ```

      ```powershell Windows theme={null}
      # Download from GitHub releases page
      # Extract the zip file
      # Navigate to the extracted folder
      ```
    </CodeGroup>
  </Step>

  <Step title="Start the server">
    Run PocketBase with the `serve` command:

    ```bash theme={null}
    ./pocketbase serve
    ```

    You'll see output like this:

    ```text theme={null}
    Server started at: http://127.0.0.1:8090
      - REST API: http://127.0.0.1:8090/api/
      - Admin UI: http://127.0.0.1:8090/_/
    ```

    <Info>
      PocketBase creates a `pb_data` directory to store your database and uploaded files. You can customize this with the `--dir` flag.
    </Info>
  </Step>

  <Step title="Create your admin account">
    Open your browser and navigate to:

    ```
    http://127.0.0.1:8090/_/
    ```

    You'll be prompted to create an admin account. Fill in your email and password—this account lets you manage your database through the Admin UI.
  </Step>

  <Step title="Create your first collection">
    In the Admin UI:

    1. Click **New Collection** in the sidebar
    2. Choose **Base collection** (for regular database records)
    3. Name it `posts`
    4. Click **Create**

    Now add some fields:

    * Click **New field** and select **Plain text**
    * Name: `title`, Check **Required**
    * Add another **Editor** field named `content`
    * Click **Save**

    <Note>
      PocketBase automatically adds `id`, `created`, and `updated` fields to every collection.
    </Note>
  </Step>

  <Step title="Test your API">
    Your REST API is automatically available. Try creating a record:

    ```bash theme={null}
    curl -X POST http://127.0.0.1:8090/api/collections/posts/records \
      -H "Content-Type: application/json" \
      -d '{
        "title": "My first post",
        "content": "Hello from PocketBase!"
      }'
    ```

    Fetch all records:

    ```bash theme={null}
    curl http://127.0.0.1:8090/api/collections/posts/records
    ```

    You should see your newly created post in the JSON response.
  </Step>
</Steps>

## Build with the Go library

If you want to extend PocketBase with custom logic, you can use it as a Go library. Here's a minimal example based on the official source:

<Steps>
  <Step title="Set up your Go project">
    ```bash theme={null}
    mkdir myapp && cd myapp
    go mod init myapp
    ```
  </Step>

  <Step title="Create main.go">
    Create a `main.go` file with this code from the PocketBase examples:

    ```go main.go theme={null}
    package main

    import (
        "log"

        "github.com/pocketbase/pocketbase"
        "github.com/pocketbase/pocketbase/core"
    )

    func main() {
        app := pocketbase.New()

        app.OnServe().BindFunc(func(se *core.ServeEvent) error {
            // registers new "GET /hello" route
            se.Router.GET("/hello", func(re *core.RequestEvent) error {
                return re.String(200, "Hello world!")
            })

            return se.Next()
        })

        if err := app.Start(); err != nil {
            log.Fatal(err)
        }
    }
    ```

    This example:

    * Creates a new PocketBase instance with `pocketbase.New()`
    * Hooks into the `OnServe()` event to add a custom route
    * Registers a `GET /hello` endpoint that returns "Hello world!"
    * Starts the application with `app.Start()`
  </Step>

  <Step title="Install dependencies and run">
    ```bash theme={null}
    go mod tidy
    go run main.go serve
    ```

    Your server starts with both the standard PocketBase API and your custom `/hello` route.
  </Step>

  <Step title="Test your custom route">
    ```bash theme={null}
    curl http://127.0.0.1:8090/hello
    ```

    You should see: `Hello world!`
  </Step>

  <Step title="Build for production">
    Create a statically linked executable:

    ```bash theme={null}
    CGO_ENABLED=0 go build
    ```

    Then deploy your single binary:

    ```bash theme={null}
    ./myapp serve
    ```
  </Step>
</Steps>

## Advanced example with plugins

The official PocketBase executable (from releases) is built with additional plugins. Here's what the full `examples/base/main.go` includes:

<CodeGroup>
  ```go JavaScript hooks theme={null}
  // Enable JavaScript hooks from pb_hooks directory
  jsvm.MustRegister(app, jsvm.Config{
      MigrationsDir: migrationsDir,
      HooksDir:      hooksDir,
      HooksWatch:    hooksWatch,
      HooksPoolSize: hooksPool,
  })
  ```

  ```go Migrations theme={null}
  // Add migrate command with JavaScript templates
  migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
      TemplateLang: migratecmd.TemplateLangJS,
      Automigrate:  automigrate,
      Dir:          migrationsDir,
  })
  ```

  ```go Static files theme={null}
  // Serve static files from pb_public directory
  app.OnServe().Bind(&hook.Handler[*core.ServeEvent]{
      Func: func(e *core.ServeEvent) error {
          if !e.Router.HasRoute(http.MethodGet, "/{path...}") {
              e.Router.GET("/{path...}", apis.Static(os.DirFS(publicDir), indexFallback))
          }
          return e.Next()
      },
      Priority: 999,
  })
  ```

  ```go GitHub updates theme={null}
  // Enable self-update from GitHub releases
  ghupdate.MustRegister(app, app.RootCmd, ghupdate.Config{})
  ```
</CodeGroup>

<Info>
  The prebuilt executables include all these plugins, allowing you to extend PocketBase with JavaScript without writing Go code.
</Info>

## Common commands

PocketBase includes several built-in commands:

| Command     | Description                                     |
| ----------- | ----------------------------------------------- |
| `serve`     | Start the HTTP server (default port: 8090)      |
| `superuser` | Create or update a superuser account            |
| `migrate`   | Run database migrations (when using Go library) |
| `--help`    | Show available commands and flags               |

### Create a superuser via CLI

```bash theme={null}
./pocketbase superuser create test@example.com password123
```

### Use a custom port

```bash theme={null}
./pocketbase serve --http=0.0.0.0:3000
```

### Enable development mode

```bash theme={null}
./pocketbase serve --dev
```

Development mode enables:

* Verbose logging to console
* SQL query logging
* Detailed error messages

<Warning>
  Don't use `--dev` in production—it exposes sensitive information in logs.
</Warning>

## SDK integration

Connect to your PocketBase API from the frontend using the official SDKs:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import PocketBase from 'pocketbase';

  const pb = new PocketBase('http://127.0.0.1:8090');

  // Create a record
  const record = await pb.collection('posts').create({
      title: 'My first post',
      content: 'Hello from PocketBase!'
  });

  // Fetch records
  const records = await pb.collection('posts').getFullList();

  // Subscribe to realtime changes
  pb.collection('posts').subscribe('*', (e) => {
      console.log(e.action); // create, update, delete
      console.log(e.record);
  });
  ```

  ```dart Dart theme={null}
  import 'package:pocketbase/pocketbase.dart';

  final pb = PocketBase('http://127.0.0.1:8090');

  // Create a record
  final record = await pb.collection('posts').create(body: {
    'title': 'My first post',
    'content': 'Hello from PocketBase!',
  });

  // Fetch records
  final records = await pb.collection('posts').getFullList();

  // Subscribe to realtime changes
  pb.collection('posts').subscribe('*', (e) {
    print(e.action); // create, update, delete
    print(e.record);
  });
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Database collections" icon="database" href="/collections/overview">
    Learn about collection types, fields, and relations
  </Card>

  <Card title="Authentication" icon="lock" href="/auth/overview">
    Set up user authentication and OAuth2 providers
  </Card>

  <Card title="File uploads" icon="file" href="/files/overview">
    Handle file uploads and image transformations
  </Card>

  <Card title="Extend with Go" icon="code" href="/go/overview">
    Add custom business logic and API routes
  </Card>
</CardGroup>

## Troubleshooting

### Port already in use

If port 8090 is busy, specify a different port:

```bash theme={null}
./pocketbase serve --http=0.0.0.0:8091
```

### Permission denied on Linux/macOS

Make the executable runnable:

```bash theme={null}
chmod +x pocketbase
```

### Database locked error

This happens if multiple PocketBase instances try to access the same `pb_data` directory. Only run one instance per data directory, or use different `--dir` paths:

```bash theme={null}
./pocketbase serve --dir=./pb_data_instance1
```

<Note>
  For production deployments, consider using process managers like systemd, Docker, or PM2 to keep PocketBase running reliably.
</Note>
