DEV Community

Alex Spinov
Alex Spinov

Posted on

Pocketbase Has a Free API — Here's How to Build a Backend in a Single File

A developer wanted a backend for his mobile app. Firebase was overkill. Supabase needed a cloud account. Then he found PocketBase — a single executable file that gives you a database, auth, file storage, and real-time subscriptions. One file. Zero dependencies.

What PocketBase Offers

PocketBase (open source, free):

  • SQLite database with REST API
  • Authentication — email/password, OAuth2 (Google, GitHub, etc.)
  • File storage — upload and serve files
  • Real-time subscriptions — Server-Sent Events
  • Admin dashboard — web UI for managing data
  • Hooks — JavaScript/Go hooks for custom logic
  • Single binary — no dependencies, ~30MB download
  • Embedded — runs on a $5 VPS, Raspberry Pi, or your laptop

Quick Start

# Download (one file!)
wget https://github.com/pocketbase/pocketbase/releases/latest/download/pocketbase_linux_amd64.zip
unzip pocketbase_linux_amd64.zip

# Run
./pocketbase serve
# API at http://127.0.0.1:8090
# Admin UI at http://127.0.0.1:8090/_/
Enter fullscreen mode Exit fullscreen mode

REST API

# List records
curl 'http://127.0.0.1:8090/api/collections/posts/records?page=1&perPage=20&sort=-created'

# Get single record
curl 'http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID'

# Create record
curl -X POST 'http://127.0.0.1:8090/api/collections/posts/records' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer USER_TOKEN' \
  -d '{
    "title": "My First Post",
    "content": "Hello, PocketBase!",
    "published": true
  }'

# Update record
curl -X PATCH 'http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID' \
  -H 'Authorization: Bearer USER_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"title": "Updated Title"}'

# Delete record
curl -X DELETE 'http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID' \
  -H 'Authorization: Bearer USER_TOKEN'

# Filter records
curl 'http://127.0.0.1:8090/api/collections/posts/records?filter=(published=true%26%26author="alice")'
Enter fullscreen mode Exit fullscreen mode

JavaScript SDK

import PocketBase from 'pocketbase';

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

// Auth
await pb.collection('users').authWithPassword('alice@example.com', 'password');

// Create
const post = await pb.collection('posts').create({
  title: 'Hello World',
  content: 'My first post',
  author: pb.authStore.model.id
});

// List with filter
const posts = await pb.collection('posts').getList(1, 20, {
  filter: 'published = true',
  sort: '-created',
  expand: 'author'
});

// Real-time subscriptions
pb.collection('posts').subscribe('*', (e) => {
  console.log(`${e.action}: ${e.record.title}`);
  // 'create', 'update', or 'delete'
});

// File upload
const formData = new FormData();
formData.append('title', 'Photo Post');
formData.append('image', fileInput.files[0]);
const record = await pb.collection('posts').create(formData);
const imageUrl = pb.files.getUrl(record, record.image);
Enter fullscreen mode Exit fullscreen mode

OAuth2 Auth

// Google login
await pb.collection('users').authWithOAuth2({ provider: 'google' });

// GitHub login
await pb.collection('users').authWithOAuth2({ provider: 'github' });

// Check auth state
if (pb.authStore.isValid) {
  console.log(`Logged in as ${pb.authStore.model.email}`);
}
Enter fullscreen mode Exit fullscreen mode

Custom Hooks (JavaScript)

// pb_hooks/main.pb.js
onRecordBeforeCreateRequest((e) => {
  // Auto-set author to current user
  e.record.set('author', e.httpContext.get('authRecord').id);
}, 'posts');

onRecordAfterCreateRequest((e) => {
  // Send notification after post created
  console.log(`New post: ${e.record.get('title')}`);
}, 'posts');
Enter fullscreen mode Exit fullscreen mode

Deploy

# It's one file — copy it anywhere
scp pocketbase user@server:/opt/pocketbase/
ssh user@server '/opt/pocketbase/pocketbase serve --http=0.0.0.0:8090'

# Or Docker
docker run -v ./pb_data:/pb_data ghcr.io/muchobien/pocketbase:latest
Enter fullscreen mode Exit fullscreen mode

PocketBase vs Firebase

PocketBase Firebase
Self-hosted (own data) Google-hosted
SQLite (simple) Firestore (complex)
Single binary SDK + Cloud console
Free forever Free tier limits
30MB download Heavy SDK

Need to scrape data into your backend? Check out my web scraping actors on Apify.

Need a lightweight backend? Email me at spinov001@gmail.com.

Top comments (0)