Showing posts with label Web Development. Show all posts
Showing posts with label Web Development. Show all posts

Saturday, 25 April 2026

PocketBase vs Supabase: VPS or Cloud – Which Backend Wins in 2026?

 


As an indie developer or small team, choosing the right backend often feels like a dilemma. You want something powerful but affordable, scalable but not overly complex. In one corner, we have Supabase, the open-source Firebase alternative built on PostgreSQL. In the other, PocketBase, a lightweight backend packaged as a single executable. Your choice of where to run them—on a $4 VPS or a managed Cloud—makes all the difference.

This post cuts through the noise. We will explore the architecture, costs, and real-world use cases of PocketBase and Supabase to help you decide which path is right for your project in 2026.


1. PocketBase: The Single-File Backend (VPS Friendly)

PocketBase is an open-source backend that compiles into a single ~15 MB executable. You download it, run it, and instantly get a SQLite database, authentication, file storage, real-time APIs, and an admin dashboard

.Deployment Simplicity: Because it is a single binary, deployment is trivial. You copy the file to a VPS and run it. No Docker, no dependencies, no complex config files.

Database: Uses embedded SQLite (with WAL mode). It is blazingly fast for read-heavy operations and simple CRUD

Cost: The software is free (MIT licensed) . You only pay for the server—as low as $4–$6 per month on a basic VPS from providers like Hetzner

Performance: A single $4 VPS (2 vCPU, 4 GB RAM) can reportedly handle 10,000+ concurrent real-time connections

    ✅ PocketBase Strengths:

    • Incredibly simple (perfect for solo developers)

    • Extremely lightweight (~20 MB RAM idle)

  • No vendor lock-in (you own your data)

  • Built-in real-time API

  • ❌ PocketBase Weaknesses:

    • Cannot scale horizontally (single-server only)

    • Not ideal for complex SQL (No JOINs, Views, or Functions)

  • No managed cloud option (you are the DevOps engineer)

  • Not for high-write workloads (SQLite write locking)


  • 2. Supabase: The PostgreSQL Powerhouse (Cloud & Self-Hosted)

    Supabase is often described as the "open-source Firebase alternative." At its core is a full PostgreSQL database, wrapped with authentication, storage, real-time subscriptions, and edge functions

    .Deployment: You can use their managed Cloud (which starts at $25/month for the Pro plan) or self-host it using Docker on your own VPS

    Database: Full PostgreSQL. This gives you access to advanced features like JOINs, Views, Triggers, Row-Level Security (RLS), and extensions like pgvector for AI apps

    Cost: The cloud plan has a generous free tier, but costs scale with usage. Self-hosting on a VPS saves money but adds complexity

    ✅ Supabase Strengths:

    • PostgreSQL ecosystem (powerful and scalable)

    • Horizontal scaling capability

    • Managed cloud option (less operational burden)

    • Enterprise features (MFA, SSO, better logging)

    ❌ Supabase Weaknesses:

    • Self-hosting is complex (requires Docker & managing 10+ containers)

  • Cloud costs grow with usage (storage, bandwidth, functions)

    • Overkill for simple projects (Side projects don't need heavy infrastructure)


    3. PocketBase vs Supabase: The Head-to-Head Comparison

    FeaturePocketBaseSupabase
    Database EngineSQLite (embedded)PostgreSQL (server)
    Deployment StyleSingle binaryDocker containers (10+ services)
    Hosting OptionsSelf-hosted onlyCloud + Self-hosted
    Minimum VPS Cost$4/monthVPS $10-20/month + labor
    Managed Cloud CostNot available$25/month (Pro plan)
    Query ComplexitySimple CRUDComplex SQL (JOINs, Views)
    Horizontal Scaling❌ No✅ Yes
    Real-time✅ Yes (SSE)✅ Yes (PostgreSQL CDC)
    Row Level Security✅ Yes (Collection Rules)✅ Yes (PostgreSQL RLS)
    Server-side LogicCustom Go/JS hooksEdge Functions (Deno)
    Best ForMVPs, side projects, internal toolsProduction apps, startups, SQL lovers

    Sources:


    4. The VPS vs. Cloud Cost Breakdown

    This is where most developers feel the pain. Let us analyze the numbers:

    Option A: PocketBase on a $4 VPS

    • PocketBase: Free (MIT License)

    • VPS (e.g., Hetzner CAX11): $4/month (2 vCPU, 4 GB RAM)

    • Backup: You manage (using litestream or cron jobs)

    • Monitoring: Basic (logs, system metrics)

    • Total Monthly Cost: ~$4–6

    Option B: Supabase Cloud

    • Supabase Pro Plan: $25/month (includes 8 GB RAM, 1 GB bandwidth)

    • Support: Included

    • Backups: Automatic

    • Monitoring: Built-in dashboards

    • Total Monthly Cost: $25+ (scales with usage)

    Option C: Supabase Self-Hosted

    • VPS Requirement: Minimum 4 GB RAM + Docker (~$20/month)

  • Supabase: Free (open-source)

  • Operational Cost: High (You manage updates, backups, security, and 10+ containers)

    • Total Monthly Cost: $20 + your time

    Verdict: If you want to minimize fixed costs and your requirements are simple, PocketBase on a $4 VPS wins by a landslide

    . If you need PostgreSQL features and want to avoid operations, Supabase Cloud is worth the $25

    .


    5. When to Choose What (Decision Framework)

    Project TypePocketBase on VPSSupabase CloudSupabase Self-Hosted
    MVP / Side ProjectBest Choice🟡 Good but expensive❌ Too complex
    Internal Tool (CRUD)Best Choice🟡 Acceptable❌ Not needed
    Production Web App❌ Not for scaleBest Choice🟡 If you have DevOps
    Needs Complex SQL (JOINs)❌ Not possibleBest Choice✅ Good
    Requires Horizontal Scaling❌ Not possibleBest Choice✅ Good
    Strict Budget (<$10/month)Best Choice❌ Too expensive❌ Too complex
    Enterprise (SAML, MFA)❌ Not possibleBest Choice✅ Possible but hard

    6. Practical Use Cases & Migration Reality

    Real-World Example: Why a Developer Chose PocketBase

    In one case, a developer building an "explanation video generator" chose PocketBase for job queue management. The reason was simple: the requirements weren't complex, and they wanted to minimize operational costs

    . They didn't need PostgreSQL's advanced features, just a reliable backend for a few thousand users.

    Migration Reality: PocketBase to Supabase

    If you start with PocketBase and later outgrow it, migration is possible but requires rebuilding:

    1. Redesign your schema for PostgreSQL (SQLite is simpler)

    2. Reimplement auth rules (PocketBase's collection rules work differently)

    3. Port your custom hooks to Supabase Edge Functions

    Pro Tip: If you anticipate needing PostgreSQL later, structure your PocketBase collections simply and store files in external S3 storage from day one

    . This makes future migration less painful.


    7. Conclusion: Which One Should You Pick in 2026?

    Your choice depends entirely on your stage and ambition:

    Pick PocketBase on a $4 VPS if you are:

    • An indie hacker building an MVP

    • Creating a side project with <10,000 users

    • Building internal tools for a small team

    • On a tight budget (<$10/month)

    Someone who values simplicity over features

    Pick Supabase Cloud if you:

    • Love PostgreSQL and need complex queries

    • Want a managed service with built-in monitoring

    • Plan to scale horizontally from day one

    • Have a budget of $25+/month for backend

    • Building a production app for customers

    Pick Supabase Self-Hosted only if you:

    • Have strong DevOps skills (managing databases, backups, containers)

    • Want to save on cloud costs but can shoulder operational burden

    • Need to run in your own infrastructure (compliance)

    Final Thoughts:
    Stop overpaying for backend services you do not use. Many indie developers run successfully on a $4 PocketBase VPS for years. As one developer put it, "PocketBase is not a replacement for Supabase, but rather another option"—and for many projects, it is the better one

    Start small. Start cheap. You can always migrate to Supabase when you need to

Friday, 20 March 2026

Flutter for Web Developers: From Zero to Your First Web App in 10 Minutes

 


If you're a web developer, you've likely heard of Flutter. Originally known as Google's toolkit for building beautiful native mobile apps, Flutter has evolved. With the stable release of Flutter for the web, a new question emerges: Should you, as a web developer, pay attention?

The answer is a resounding yes. Flutter isn't just for mobile anymore; it's a powerful framework for building interactive, performant, and visually consistent web applications from a single codebase.

What is Flutter?
Flutter is an open-source UI software development kit created by Google. It uses the Dart programming language. Unlike traditional web frameworks that rely on a bridge to communicate with the browser's DOM (Document Object Model), Flutter compiles your code straight into standard HTML, CSS, and JavaScript. It also has an option to compile to WebAssembly for even faster performance.

For a web developer, this means you can leverage your existing knowledge of UI structure and design while writing in a new, component-based way.

How Your Web Dev Skills Translate
Moving to Flutter isn't starting from scratch. Many core concepts will feel familiar:

Web Development ConceptFlutter Equivalent
HTML Elements (divs, spans)Widgets (Container, Row, Column, Text)
CSS Flexbox/GridRow, Column, Expanded, Flexible widgets
CSS Styling (classes)Widget properties & Theme system
JavaScript Functions/ComponentsStateless and Stateful Widgets
Package Managers (npm/yarn)pubspec.yaml and pub.dev

Flutter vs. Traditional Web Frameworks

  • React/Vue.js: These are JavaScript libraries that work with the DOM. Flutter is a complete SDK that draws every pixel itself. This gives Flutter apps a highly consistent look across all browsers.

  • Performance: Because Flutter doesn't rely on the DOM for rendering, it can achieve silky-smooth animations (60-120 fps) that are often more consistent than complex JavaScript animations.

  • Single Codebase: The biggest draw: write one UI in Dart, and deploy it as a web app, an Android app, and an iOS app. For businesses, this is a game-changer.

When Should Web Developers Use Flutter?
Flutter for web is not always the right tool, but it excels in specific scenarios:

  1. Progressive Web Apps (PWAs): Flutter creates installable, offline-capable PWAs with a native-like feel.

  2. Single-Page Applications (SPAs): It's ideal for complex, interactive dashboards and tools.

  3. Mobile-First Web Experiences: If your primary audience is on mobile browsers, Flutter provides a pixel-perfect, app-like experience.

  4. Code Reuse: If you already have a Flutter mobile app, adding a web version is incredibly efficient.

Getting Started: Your First Flutter Web Project
Ready to dip your toes in? It's simpler than you might think.

  1. Install Flutter: Download the Flutter SDK from the official website.

  2. Enable Web Support: Open your terminal and run:

    bash
flutter config --enable-web

Create a New Project:

bash
flutter create my_first_web_app
cd my_first_web_app

Run in a Browser:

bash
flutter run -d chrome
  1. Explore the Code: Open the lib/main.dart file. You'll see a widget tree. Try changing the text in the Center widget and save the file—the browser will hot-reload instantly.

Key Takeaway
Flutter represents a shift in web development. It's a powerful tool that blends the speed of native apps with the reach of the web. For the curious web developer, learning Flutter isn't about abandoning your current stack; it's about adding a versatile new tool to your arsenal.

Have you tried Flutter for the web yet? What challenges or successes have you faced? Let us know in the comments below!

 

Tuesday, 10 March 2026

Building Modern Web Applications with Angular and PocketBase: A Complete Guide

 


In today's fast-paced development world, choosing the right tech stack can make or break your project timeline. While Angular remains one of the most powerful frontend frameworks, developers often struggle with backend setup complexity. Enter PocketBase – an open-source backend that gives you authentication, database, and file storage in a single file.

In this guide, I'll show you how to build a complete web application using Angular + PocketBase, combining the best of both worlds.


Why Angular + PocketBase?

Angular Benefits:

  • Full-featured MVC framework with TypeScript support

  • Built-in dependency injection

  • Powerful CLI for scaffolding

  • RxJS for reactive programming

  • Enterprise-ready architecture

PocketBase Benefits:

Perfect For:

  • MVPs and startups needing rapid development

  • Internal tools and dashboards

  • E-commerce applications

  • Content management systems

  • Real-time collaborative apps


Prerequisites

Before we begin, ensure you have:

  • Node.js (v18 or later)

  • Angular CLI (npm install -g @angular/cli)

  • PocketBase executable (download from pocketbase.io)

  • Basic knowledge of TypeScript and Angular


Step 1: Setting Up PocketBase

1. Download and Install

bash
# For Linux/Mac
wget https://github.com/pocketbase/pocketbase/releases/download/v0.22.0/pocketbase_0.22.0_linux_amd64.zip
unzip pocketbase_0.22.0_linux_amd64.zip

# For Windows
# Download the .exe file from GitHub releases

2. Start PocketBase

bash
./pocketbase serve

Your PocketBase server will run at http://127.0.0.1:8090. Visit the admin UI at http://127.0.0.1:8090/_/ and create your admin account.

3. Create Your First Collection
In the admin UI, create a new collection called posts with fields:

  • title (text, required)

  • content (text, required)

  • published (boolean, default false)

  • created (date, auto)


Step 2: Creating Angular Application

1. Generate New Angular Project

bash
ng new angular-pocketbase-app --style=css --routing
cd angular-pocketbase-app

2. Install PocketBase SDK

bash
npm install pocketbase

3. Create PocketBase Service
Generate a service to handle all PocketBase interactions:

bash
ng generate service services/pocketbase

4. Configure Environment Variables
Update src/environments/environment.ts:

typescript
export const environment = {
  production: false,
  pocketBaseUrl: 'http://127.0.0.1:8090'
};

Step 3: Building the PocketBase Service

src/app/services/pocketbase.service.ts

typescript
import { Injectable } from '@angular/core';
import PocketBase from 'pocketbase';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class PocketbaseService {
  private pb: PocketBase;

  constructor() {
    this.pb = new PocketBase(environment.pocketBaseUrl);
  }

  // Authentication methods
  async login(email: string, password: string) {
    return await this.pb.collection('users').authWithPassword(email, password);
  }

  async register(email: string, password: string, passwordConfirm: string) {
    return await this.pb.collection('users').create({
      email,
      password,
      passwordConfirm
    });
  }

  logout() {
    this.pb.authStore.clear();
  }

  get currentUser() {
    return this.pb.authStore.model;
  }

  // Posts CRUD operations
  async getPosts() {
    return await this.pb.collection('posts').getFullList({
      sort: '-created',
      filter: 'published = true'
    });
  }

  async createPost(data: any) {
    return await this.pb.collection('posts').create(data);
  }

  async updatePost(id: string, data: any) {
    return await this.pb.collection('posts').update(id, data);
  }

  async deletePost(id: string) {
    return await this.pb.collection('posts').delete(id);
  }

  // Real-time subscriptions
  subscribeToPosts(callback: (data: any) => void) {
    return this.pb.collection('posts').subscribe('*', (e) => {
      callback(e);
    });
  }
}

Step 4: Creating Components

1. Posts List Component

bash
ng generate component posts-list

src/app/posts-list/posts-list.component.ts

typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
import { PocketbaseService } from '../services/pocketbase.service';

@Component({
  selector: 'app-posts-list',
  templateUrl: './posts-list.component.html',
  styleUrls: ['./posts-list.component.css']
})
export class PostsListComponent implements OnInit, OnDestroy {
  posts: any[] = [];
  private unsubscribe: any;

  constructor(private pb: PocketbaseService) {}

  async ngOnInit() {
    await this.loadPosts();
    this.setupRealtime();
  }

  async loadPosts() {
    this.posts = await this.pb.getPosts();
  }

  setupRealtime() {
    this.unsubscribe = this.pb.subscribeToPosts((data) => {
      console.log('Realtime update:', data);
      this.loadPosts(); // Reload posts on any change
    });
  }

  ngOnDestroy() {
    if (this.unsubscribe) {
      this.unsubscribe();
    }
  }
}

src/app/posts-list/posts-list.component.html

html
<div class="posts-container">
  <h2>Latest Posts</h2>
  <div class="posts-grid">
    <div *ngFor="let post of posts" class="post-card">
      <h3>{{ post.title }}</h3>
      <p>{{ post.content }}</p>
      <small>Published: {{ post.created | date }}</small>
    </div>
  </div>
</div>

Step 5: Adding Authentication UI

1. Login Component

bash
ng generate component login

src/app/login/login.component.ts

typescript
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { PocketbaseService } from '../services/pocketbase.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  email = '';
  password = '';
  error = '';

  constructor(
    private pb: PocketbaseService,
    private router: Router
  ) {}

  async onSubmit() {
    try {
      await this.pb.login(this.email, this.password);
      this.router.navigate(['/posts']);
    } catch (err: any) {
      this.error = err.message || 'Login failed';
    }
  }
}

Step 6: Real-time Features with RxJS

PocketBase's real-time capabilities work beautifully with Angular's RxJS. Here's an enhanced service using Observables:

typescript
import { Observable } from 'rxjs';

// In pocketbase.service.ts
watchPosts(): Observable<any> {
  return new Observable((observer) => {
    const unsubscribe = this.pb.collection('posts').subscribe('*', (data) => {
      observer.next(data);
    });
    
    return () => unsubscribe();
  });
}

Now you can use this in components:

typescript
this.pb.watchPosts().subscribe(update => {
  console.log('Real-time update:', update);
  // Update your local data accordingly
});

Step 7: Deployment Considerations

Building Angular for Production

bash
ng build --prod

Deploying PocketBase

  1. Upload PocketBase binary to your VPS or cloud server

  2. Set up as a systemd service for auto-restart

  3. Configure environment variables

  4. Use Nginx as reverse proxy for SSL

Sample systemd service file:

ini
[Unit]
Description=PocketBase service

[Service]
Type=simple
User=youruser
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http=0.0.0.0:8090
Restart=on-failure

[Install]
WantedBy=multi-user.target

Step 8: Security Best Practices

  1. Environment Variables: Never hardcode credentials

  2. CORS Configuration: Configure PocketBase CORS properly

  3. Validation Rules: Set collection validation rules in PocketBase admin

  4. API Rules: Implement proper collection permissions

  5. HTTPS: Always use SSL in production


Conclusion

Angular + PocketBase creates a powerful, modern stack that significantly reduces development time while maintaining scalability and performance. PocketBase handles all backend complexity, letting you focus on building amazing Angular applications.

Key Takeaways:

  • PocketBase provides instant backend with zero configuration

  • Angular offers robust structure for large applications

  • Real-time features are simple to implement

  • Perfect for startups and MVPs

  • Open-source and self-hosted (no vendor lock-in)


Next Steps

  • Explore PocketBase's file upload capabilities

  • Implement OAuth authentication (Google, GitHub)

  • Add search functionality

  • Build an admin dashboard

  • Deploy to production with Docker