All posts
March 16, 2026·5 min read·Long Nguyen · CTO, ERPFit·Updated June 17, 2026
open-sourcetypescriptbuninfrastructure
Our Open-Source Stack: Bun, Hono, PostgreSQL, Cloudflare

Our Open-Source Stack: Bun, Hono, PostgreSQL, Cloudflare

Why ERPFit builds on Bun, Hono, PostgreSQL and Cloudflare: the open-source stack we run in production daily, with no license fees and no vendor lock-in.

Table of Contents

ERPFit doesn't sell packaged software. We build solutions for each business, then transfer ownership so they run it themselves. That means our tech stack must serve two needs: we develop fast, and clients don't get locked into anyone.

Open source solves both. No license fees, no vendor lock-in, and when needed — any developer can read the code, fix it, or replace it.

Runtime: Bun

We default to Bun because it runs faster than Node.js, supports TypeScript natively, and bundles several tools into one. Before Bun, we used Node.js. We didn't switch for the hype — we switched for three practical reasons:

  • Significantly faster startup. Automation scripts running daily (health checks, backup verification, data sync) need to start in milliseconds, not seconds. Per Bun's own benchmarks, the runtime starts several times faster than Node.js for small scripts — which matches our internal experience.
  • Native TypeScript. No tsc, no ts-node, no tsx. Write .ts, run directly. Dramatically less friction in development.
  • Built-in test runner, bundler, package manager. Fewer tools = less to maintain. In a small team, this matters.

A typical automation script of ours is this compact:

// health-check.ts — run directly with `bun run health-check.ts`
const res = await fetch('https://erpfit.com/health')
if (!res.ok) {
  await fetch(process.env.TELEGRAM_WEBHOOK!, {
    method: 'POST',
    body: JSON.stringify({ text: 'erpfit.com DOWN' }),
  })
}

Bun isn't perfect. Some npm packages with native bindings still have issues. But with a TypeScript-first stack, we rarely need native modules. The trade-off is worth it.

Web Framework: Hono

Hono is a lightweight web framework that runs on every runtime (Bun, Deno, Cloudflare Workers, Node.js) with an Express-style API — which is exactly why we chose it. Specifically:

  • Lightweight. Bundle size is negligible compared to Express or Fastify. Matters when running on small VPS instances.
  • Familiar API. If you know Express, you know Hono. Same middleware pattern.
  • JSX support. Hono has its own JSX renderer — no React needed. The erpfit.com website runs Hono JSX, server-rendered, no client-side hydration. Fast, simple.
  • Runtime-agnostic. If Bun stops being the right choice someday, switching to Deno or Node.js means swapping one adapter.

A basic Hono route is just a few lines:

import { Hono } from 'hono'

const app = new Hono()
app.get('/health', (c) => c.json({ ok: true }))

export default app

Hono pairs with tRPC for APIs that need end-to-end type safety — clients get autocompletion, servers validate automatically. This pattern works well in TypeScript monorepos. We run our Craft tools on the same foundation.

Database: PostgreSQL (and MariaDB When Needed)

PostgreSQL is the default for every new project because it handles nearly everything in one engine. The reason is simple: relational, JSON, full-text search, PostGIS for geolocation, good at small and large scale.

Our widget platform uses PostgreSQL + PostGIS for store locators — calculating distances, finding nearest stores. No need for a separate geo service. Our PIM platform for ecommerce sits on the same database too.

MariaDB is still used when appropriate — ERPNext runs on MariaDB, WordPress uses MySQL. We're not dogmatic about databases — we use what fits the problem best.

Infrastructure: Cloudflare + Linux + Docker

Our infrastructure sits on Cloudflare at the edge and Docker on Linux at the core — nearly free and entirely open source. Cloudflare handles DNS, CDN, SSL, DDoS protection, and Cloudflare Tunnel for on-premise services without needing a public IP.

Servers run on VPS instances and on-premise Proxmox. Docker + Coolify for container management, Traefik as reverse proxy. All open source.

Daily backups with 30-day retention, offsite copies via SFTP. Monitoring with Uptime Kuma — 19+ service endpoints (internal data), Telegram alerts within minutes of any incident. We wrote up the full setup in our guide on uptime monitoring with Uptime Kuma.

Why Not Cloud Managed Services?

For Vietnamese SMEs, cloud managed services are usually pricier and more locking than a few VPS running Docker — so we avoid them. AWS, GCP, Azure all have managed databases, managed Kubernetes, managed everything. But for Vietnamese SMEs:

  • Disproportionate cost. The smallest RDS instance already costs more than a VPS running PostgreSQL + 5 app containers.
  • Real vendor lock-in. Lambda, DynamoDB, Cloud Functions — code written for a specific cloud is hard to move. We want our clients to be free.
  • Simpler at SME scale. 2-3 VPS instances, Docker Compose, Traefik — enough for nearly all of our clients' needs (internal data). Kubernetes is overkill when you don't have 10 microservices.

This doesn't mean cloud managed services are wrong — just that they don't fit our clients' profile.

Principles for Choosing Technology

The principles boil down to one sentence: pick boring technology, run fewer tools, default to open source, and keep everything transferable. After a few years of experimentation, we've distilled a few principles:

  • Prefer boring technology. PostgreSQL is more boring than MongoDB. Linux is more boring than serverless. Boring means stable, well-documented, easy to find support for.
  • Fewer tools = fewer problems. Every tool added to the stack is another thing to update, monitor, debug. Bun replaces Node + tsc + jest + npm with a single tool.
  • Open source first, pay when needed. Use Mautic instead of Mailchimp, Uptime Kuma instead of Datadog, Coolify instead of Vercel. Open source isn't always better — but it's always the right starting point.
  • Must be transferable. The stack must be something another developer can take over. TypeScript + PostgreSQL + Docker — nearly everyone knows these. That's the biggest advantage.

The stack matters less than how you use it. But choosing the right stack from the start saves a lot of time and money down the road — especially for small businesses, where every technology decision directly impacts operating costs.

Frequently asked questions

Why choose Bun over Node.js?
Bun runs TypeScript natively (executes .ts directly), starts faster per Bun's benchmarks, and folds the test runner, bundler and package manager into one binary. For a small team, fewer tools means less to maintain. Node.js is still fine, but Bun removes daily friction.
PostgreSQL or MySQL/MariaDB?
We default to PostgreSQL because it combines relational data, JSON, full-text search and PostGIS in one engine. We still use MariaDB/MySQL when the platform requires it (ERPNext, WordPress). We're not dogmatic — we pick the database that fits the problem best.
Is self-hosting cheaper than cloud managed services?
For SMEs, almost always. The smallest RDS instance already costs more than a single VPS running PostgreSQL plus five app containers. Two or three VPS instances with Docker and Traefik cover most needs while avoiding vendor lock-in.
What does Hono offer over Express?
Hono is much lighter, runs on every runtime (Bun, Deno, Cloudflare Workers, Node.js), and ships its own JSX renderer so you can server-render without React. Its API closely mirrors Express, so if you know Express, picking up Hono takes almost no learning time.
Can clients run this stack themselves?
That's the design goal. TypeScript + PostgreSQL + Docker are widely known technologies most developers already understand, with no license fees or vendor lock-in. We build, then hand over the full source code and infrastructure so clients stay fully in control.
LN
Long Nguyen
CTO, ERPFit

CTO at ERPFit. Hands-on builder of the technical infrastructure, the Craft tool suite, and the service platform for Vietnamese businesses.

Share:𝕏FBin